Skip to content

Commit ee243ff

Browse files
authored
feat(authenticator): Add a material3 datepicker to date fields. (#34)
1 parent da57f28 commit ee243ff

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

authenticator/src/main/java/com/amplifyframework/ui/authenticator/ui/DateInputField.kt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,41 @@
1515

1616
package com.amplifyframework.ui.authenticator.ui
1717

18+
import android.widget.DatePicker
1819
import androidx.compose.foundation.layout.fillMaxWidth
1920
import androidx.compose.foundation.text.KeyboardActions
2021
import androidx.compose.foundation.text.KeyboardOptions
22+
import androidx.compose.material3.Button
23+
import androidx.compose.material3.DatePicker
24+
import androidx.compose.material3.DatePickerDialog
25+
import androidx.compose.material3.ExperimentalMaterial3Api
26+
import androidx.compose.material3.Icon
27+
import androidx.compose.material3.IconButton
2128
import androidx.compose.material3.OutlinedTextField
2229
import androidx.compose.material3.Text
30+
import androidx.compose.material3.rememberDatePickerState
2331
import androidx.compose.runtime.Composable
32+
import androidx.compose.runtime.getValue
33+
import androidx.compose.runtime.mutableStateOf
34+
import androidx.compose.runtime.remember
35+
import androidx.compose.runtime.setValue
2436
import androidx.compose.ui.Modifier
2537
import androidx.compose.ui.focus.FocusDirection
2638
import androidx.compose.ui.platform.LocalFocusManager
39+
import androidx.compose.ui.res.painterResource
40+
import androidx.compose.ui.res.stringResource
2741
import androidx.compose.ui.text.AnnotatedString
2842
import androidx.compose.ui.text.input.ImeAction
2943
import androidx.compose.ui.text.input.KeyboardType
3044
import androidx.compose.ui.text.input.OffsetMapping
3145
import androidx.compose.ui.text.input.TransformedText
3246
import androidx.compose.ui.text.input.VisualTransformation
47+
import com.amplifyframework.ui.authenticator.R
3348
import com.amplifyframework.ui.authenticator.forms.FieldConfig
3449
import com.amplifyframework.ui.authenticator.forms.MutableFieldState
3550
import com.amplifyframework.ui.authenticator.strings.StringResolver
51+
import java.time.Duration
52+
import java.time.LocalDate
3653

3754
private val invalidDateChars = """[^\d-]+""".toRegex()
3855

@@ -70,6 +87,7 @@ private object DateVisualTransformation : VisualTransformation {
7087
}
7188
}
7289

90+
@OptIn(ExperimentalMaterial3Api::class)
7391
@Composable
7492
internal fun DateInputField(
7593
fieldConfig: FieldConfig.Date,
@@ -81,6 +99,9 @@ internal fun DateInputField(
8199

82100
val label = StringResolver.label(fieldConfig)
83101
val hint = StringResolver.hint(fieldConfig)
102+
103+
var dialogVisible by remember { mutableStateOf(false) }
104+
84105
OutlinedTextField(
85106
modifier = modifier,
86107
enabled = enabled,
@@ -98,6 +119,14 @@ internal fun DateInputField(
98119
keyboardActions = KeyboardActions(
99120
onNext = { focusManager.moveFocus(FocusDirection.Next) }
100121
),
122+
trailingIcon = {
123+
IconButton(onClick = { dialogVisible = true }) {
124+
Icon(
125+
painter = painterResource(R.drawable.ic_authenticator_calendar),
126+
contentDescription = stringResource(R.string.amplify_ui_authenticator_field_a11y_date_picker)
127+
)
128+
}
129+
},
101130
supportingText = {
102131
AuthenticatorFieldError(
103132
modifier = Modifier.fillMaxWidth(),
@@ -106,6 +135,28 @@ internal fun DateInputField(
106135
)
107136
}
108137
)
138+
139+
if (dialogVisible) {
140+
val datePickerState = rememberDatePickerState()
141+
DatePickerDialog(
142+
onDismissRequest = { dialogVisible = false },
143+
confirmButton = {
144+
Button(
145+
onClick = {
146+
datePickerState.selectedDateMillis?.let {
147+
// Convert the UTC milliseconds into an ISO 8601 date string
148+
fieldState.content = LocalDate.ofEpochDay(Duration.ofMillis(it).toDays()).toString()
149+
}
150+
dialogVisible = false
151+
}
152+
) {
153+
Text(stringResource(R.string.amplify_ui_authenticator_button_submit))
154+
}
155+
}
156+
) {
157+
DatePicker(state = datePickerState, showModeToggle = false)
158+
}
159+
}
109160
}
110161

111162
private fun filterDate(value: String): String {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector android:height="24dp" android:tint="#000000"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M19,4h-1V2h-2v2H8V2H6v2H5C3.89,4 3.01,4.9 3.01,6L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V6C21,4.9 20.1,4 19,4zM19,20H5V10h14V20zM9,14H7v-2h2V14zM13,14h-2v-2h2V14zM17,14h-2v-2h2V14zM9,18H7v-2h2V18zM13,18h-2v-2h2V18zM17,18h-2v-2h2V18z"/>
5+
</vector>

authenticator/src/main/res/values/fields.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
<item quantity="other">* at least %d characters</item>
5757
</plurals>
5858

59+
<!-- Date field specific strings -->
60+
<string name="amplify_ui_authenticator_field_a11y_date_picker">Select date</string>
61+
5962
<!-- Confirm Password field specific strings -->
6063
<string name="amplify_ui_authenticator_field_hint_password_confirm">Re-enter your password</string>
6164
<string name="amplify_ui_authenticator_field_warn_unmatched_password">Passwords do not match</string>

0 commit comments

Comments
 (0)