diff --git a/README.md b/README.md
index f032a87..3db8d59 100644
--- a/README.md
+++ b/README.md
@@ -1,70 +1,34 @@
# Compose DateTimePicker
-[](https://central.sonatype.com/artifact/io.github.kez-lab/compose-date-time-picker)
-[](https://opensource.org/licenses/Apache-2.0)
-[](http://kotlinlang.org)
-[](https://github.com/JetBrains/compose-multiplatform)
+[](./README_KO.md)
-A Compose Multiplatform date and time picker library that provides a consistent UI across Android, iOS, Desktop, and Web platforms.
+A generic, customizable, and multiplatform date and time picker library for Compose Multiplatform.
+It provides consistent UI components across Android, iOS, Desktop (JVM), and Web (Wasm).
-[π Blog: Development Journey (Korean)](https://velog.io/@kej_ad/AndroidCompose-Year-Month-DatePicker-%EB%A7%8C%EB%93%A4%EA%B8%B0)
+## Features
----
+* **Multiplatform Support**: seamless integration for Android, iOS, Desktop (JVM), and Web (Wasm).
+* **TimePicker**: Supports both 12-hour (AM/PM) and 24-hour formats.
+* **YearMonthPicker**: A dedicated component for selecting years and months.
+* **Customizable**: Extensible API allowing custom content rendering, styling, and configuration.
+* **State Management**: simplified state handling with `rememberTimePickerState` and `rememberYearMonthPickerState`.
+* **Accessibility**: Built with accessibility in mind, supporting screen readers and navigation.
-## π± Screenshots
+## Installation
-### Sample Screens
+Add the dependency to your version catalog or build file.
-
-
-
- 
- TimePicker Sample
- |
-
- 
- DatePicker Sample
- |
-
-
+### Version Catalog (libs.versions.toml)
-### BottomSheet Integration
-
-
-
-
- 
- BottomSheet Sample
- Date and time selection in bottom sheet
- |
-
-
-
-> **Demo**: The animation above shows the complete interaction flow for date and time selection using bottom sheets.
-
----
-
-## β¨ Features
-
-- π **Multiplatform**: Android, iOS, Desktop (JVM), and Web support
-- β° **TimePicker**: 12-hour and 24-hour format support
-- π
**YearMonthPicker**: Year and month selection component
-- π± **BottomSheet Ready**: Works seamlessly with Material3 ModalBottomSheet
-- π¨ **Fully Customizable**: Colors, fonts, sizes, visible item counts, and more
-- π **Responsive Layout**: Automatically adapts to screen sizes
-- π§© **Compose Native**: Seamless integration with Jetpack Compose and Compose Multiplatform
-
-### Why Use This Library?
-
-- **Consistent UX**: Same design and behavior across all platforms
-- **KMP Optimized**: Built on kotlinx-datetime for stable cross-platform operation
-- **Extensible**: Build custom pickers using the provided base components
+```toml
+[versions]
+composeDateTimePicker = "0.4.0"
----
-
-## π¦ Installation
+[libraries]
+compose-date-time-picker = { module = "io.github.kez-lab:compose-date-time-picker", version.ref = "composeDateTimePicker" }
+```
-### Gradle (Kotlin DSL)
+### Gradle (build.gradle.kts)
```kotlin
dependencies {
@@ -72,144 +36,102 @@ dependencies {
}
```
-### Platform Support
+## Usage
-| Platform | Status | Minimum Version |
-|----------|--------|-----------------|
-| Android | β
Stable | API 24+ |
-| iOS | π§ͺ Beta | iOS 13+ |
-| Desktop (JVM) | β
Stable | JVM 17+ |
-| Web (JS) | β οΈ Experimental | Modern browsers |
+### TimePicker
----
+Use `TimePicker` for time selection. It supports both 12-hour and 24-hour formats.
-## π Quick Start
-
-### 1. TimePicker (24-Hour Format)
+#### 1. 24-Hour Format
```kotlin
-import androidx.compose.runtime.*
-import com.kez.picker.rememberPickerState
+import androidx.compose.runtime.Composable
import com.kez.picker.time.TimePicker
+import com.kez.picker.rememberTimePickerState
import com.kez.picker.util.TimeFormat
import com.kez.picker.util.currentHour
import com.kez.picker.util.currentMinute
@Composable
-fun TimePickerExample() {
- // Manage picker state
- val hourState = rememberPickerState(currentHour)
- val minuteState = rememberPickerState(currentMinute)
-
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier.fillMaxWidth().padding(16.dp)
- ) {
- TimePicker(
- hourPickerState = hourState,
- minutePickerState = minuteState,
- timeFormat = TimeFormat.HOUR_24
- )
-
- Spacer(modifier = Modifier.height(16.dp))
-
- // Display selected time
- Text(
- text = "Selected: %02d:%02d".format(
- hourState.selectedItem,
- minuteState.selectedItem
- ),
- style = MaterialTheme.typography.titleLarge
- )
- }
+fun TimePicker24hExample() {
+ val state = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ timeFormat = TimeFormat.HOUR_24
+ )
+
+ TimePicker(
+ state = state
+ )
}
```
-### 2. TimePicker (12-Hour Format with AM/PM)
+#### 2. 12-Hour Format (AM/PM)
```kotlin
+import androidx.compose.runtime.Composable
+import com.kez.picker.time.TimePicker
+import com.kez.picker.rememberTimePickerState
+import com.kez.picker.util.TimeFormat
import com.kez.picker.util.TimePeriod
+import com.kez.picker.util.currentHour
+import com.kez.picker.util.currentMinute
@Composable
-fun TimePicker12HourExample() {
- // Convert current time to 12-hour format
- val hour12 = if (currentHour > 12) currentHour - 12
- else if (currentHour == 0) 12
- else currentHour
- val period = if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM
-
- val hourState = rememberPickerState(hour12)
- val minuteState = rememberPickerState(currentMinute)
- val periodState = rememberPickerState(period)
-
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier.fillMaxWidth().padding(16.dp)
- ) {
- TimePicker(
- hourPickerState = hourState,
- minutePickerState = minuteState,
- periodPickerState = periodState,
- timeFormat = TimeFormat.HOUR_12 // Enable 12-hour format
- )
-
- Spacer(modifier = Modifier.height(16.dp))
-
- Text(
- text = "%02d:%02d %s".format(
- hourState.selectedItem,
- minuteState.selectedItem,
- periodState.selectedItem // AM or PM
- ),
- style = MaterialTheme.typography.titleLarge
- )
- }
+fun TimePicker12hExample() {
+ // Handling of 12-hour format conversion is now done internally by the state
+ val state = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ timeFormat = TimeFormat.HOUR_12
+ )
+
+ TimePicker(
+ state = state
+ )
}
```
-### 3. YearMonthPicker
+### YearMonthPicker
+
+Use `YearMonthPicker` for selecting a specific month in a year.
```kotlin
+import androidx.compose.runtime.Composable
import com.kez.picker.date.YearMonthPicker
+import com.kez.picker.rememberYearMonthPickerState
import com.kez.picker.util.currentDate
@Composable
fun YearMonthPickerExample() {
- // Using kotlinx-datetime (KMP standard)
- val yearState = rememberPickerState(currentDate.year)
- val monthState = rememberPickerState(currentDate.monthNumber)
-
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier.fillMaxWidth().padding(16.dp)
- ) {
- YearMonthPicker(
- yearPickerState = yearState,
- monthPickerState = monthState
- )
-
- Spacer(modifier = Modifier.height(16.dp))
-
- Text(
- text = "Selected: ${yearState.selectedItem}/${monthState.selectedItem}",
- style = MaterialTheme.typography.titleLarge
- )
- }
+ val state = rememberYearMonthPickerState(
+ initialYear = currentDate.year,
+ initialMonth = currentDate.monthNumber
+ )
+
+ YearMonthPicker(
+ state = state
+ )
}
```
-### 4. BottomSheet Integration
+### BottomSheet Integration
+
+The pickers work seamlessly within a `ModalBottomSheet` or other dialog components.
```kotlin
import androidx.compose.material3.*
+import androidx.compose.runtime.*
+import com.kez.picker.time.TimePicker
+import com.kez.picker.rememberTimePickerState
+import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomSheetPickerExample() {
var showBottomSheet by remember { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState()
- val hourState = rememberPickerState(currentHour)
- val minuteState = rememberPickerState(currentMinute)
+ val state = rememberTimePickerState()
val scope = rememberCoroutineScope()
Button(onClick = { showBottomSheet = true }) {
@@ -221,171 +143,37 @@ fun BottomSheetPickerExample() {
onDismissRequest = { showBottomSheet = false },
sheetState = sheetState
) {
- Column(
- modifier = Modifier.fillMaxWidth().padding(16.dp),
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- TimePicker(
- hourPickerState = hourState,
- minutePickerState = minuteState,
- timeFormat = TimeFormat.HOUR_24
- )
-
- Button(
- onClick = {
- scope.launch {
- sheetState.hide()
- showBottomSheet = false
- }
- }
- ) {
- Text("Confirm")
- }
- }
+ TimePicker(state = state)
+ // Add confirmation buttons logic here
}
}
}
```
----
-
-## π API Reference
-
-### TimePicker Parameters
-
-| Parameter | Type | Default | Description |
-| --- | --- | --- | --- |
-| `modifier` | `Modifier` | `Modifier` | Modifier to be applied to the composable |
-| `hourPickerState` | `PickerState` | `rememberPickerState(currentHour)` | State for the hour picker |
-| `minutePickerState` | `PickerState` | `rememberPickerState(currentMinute)` | State for the minute picker |
-| `periodPickerState` | `PickerState?` | `null` | State for AM/PM picker (12-hour format only) |
-| `timeFormat` | `TimeFormat` | `TimeFormat.HOUR_24` | Time format (`HOUR_12` or `HOUR_24`) |
-| `startTime` | `LocalDateTime` | `currentDateTime` | Initial time value |
-| `minuteItems` | `List` | `0..59` | List of minutes to display |
-| `hourItems` | `List` | `1..12` (12-hour) / `0..23` (24-hour) | List of hours to display |
-| `periodItems` | `List` | `[AM, PM]` | List of periods (12-hour format only) |
-| `visibleItemsCount` | `Int` | `3` | Number of items visible at once |
-| `itemPadding` | `PaddingValues` | `PaddingValues(8.dp)` | Padding for each item |
-| `textStyle` | `TextStyle` | `TextStyle(fontSize = 16.sp)` | Text style for unselected items |
-| `selectedTextStyle` | `TextStyle` | `TextStyle(fontSize = 22.sp)` | Text style for the selected item |
-| `dividerColor` | `Color` | `LocalContentColor.current` | Color of the divider line |
-| `fadingEdgeGradient` | `Brush` | (default gradient) | Gradient for fading edges |
-| `dividerThickness` | `Dp` | `1.dp` | Thickness of the divider line |
-| `pickerWidth` | `Dp` | `80.dp` | Width of each picker column |
-
-### YearMonthPicker Parameters
-
-| Parameter | Type | Default | Description |
-| --- | --- | --- | --- |
-| `modifier` | `Modifier` | `Modifier` | Modifier to be applied to the composable |
-| `yearPickerState` | `PickerState` | `rememberPickerState(currentDate.year)` | State for the year picker |
-| `monthPickerState` | `PickerState` | `rememberPickerState(currentDate.monthNumber)` | State for the month picker |
-| `startLocalDate` | `LocalDate` | `currentDate` | Initial date value |
-| `yearItems` | `List` | `1900..2100` | List of years to display |
-| `monthItems` | `List` | `1..12` | List of months to display |
-| `visibleItemsCount` | `Int` | `3` | Number of items visible at once |
-| `itemPadding` | `PaddingValues` | `PaddingValues(8.dp)` | Padding for each item |
-| `textStyle` | `TextStyle` | `TextStyle(fontSize = 16.sp)` | Text style for unselected items |
-| `selectedTextStyle` | `TextStyle` | `TextStyle(fontSize = 24.sp)` | Text style for the selected item |
-| `dividerColor` | `Color` | `LocalContentColor.current` | Color of the divider line |
-| `fadingEdgeGradient` | `Brush` | (default gradient) | Gradient for fading edges |
-| `dividerThickness` | `Dp` | `2.dp` | Thickness of the divider line |
-| `pickerWidth` | `Dp` | `100.dp` | Width of each picker column |
-
-### Custom Picker Extension
-
-You can extend the library by using the `Picker` composable directly to create custom pickers:
-
-```kotlin
-@Composable
-fun CustomPicker() {
- Picker(
- state = rememberPickerState(0),
- items = listOf("Option 1", "Option 2", "Option 3"),
- // ... customization parameters
- )
-}
-```
-
----
-
-## π» Running the Sample Project
-
-### Android
-
-```bash
-./gradlew :sample:installDebug
-```
-
-The app will be installed on your connected device or emulator.
-
-### Desktop (JVM)
-
-In Android Studio or IntelliJ IDEA:
-1. Open `sample/src/desktopMain/kotlin/com/kez/picker/sample/Main.kt`
-2. Click the run button next to the `main()` function
-
-Or run via Gradle:
-```bash
-./gradlew :sample:desktopRun -DmainClass=com.kez.picker.sample.MainKt --quiet
-```
-
-### iOS
+## API Reference
-Open the `iosApp/` project in Xcode and run.
+### TimePicker
-### Web
+| Parameter | Description | Default |
+| :--- | :--- | :--- |
+| `state` | The state object to control the picker. | `rememberTimePickerState()` |
+| `startTime` | The initial time to set the picker to. | `currentDateTime` |
+| `visibleItemsCount` | Number of items visible in the list. | `3` |
+| `textStyle` | Style for unselected items. | `16.sp` |
+| `selectedTextStyle` | Style for selected item. | `22.sp` |
+| `dividerColor` | Color of the selection dividers. | `LocalContentColor.current` |
-Build and serve the web application:
-```bash
-./gradlew :sample:wasmJsBrowserDevelopmentRun
-```
-
----
-
-## π€ Contributing
-
-Contributions are welcome! Whether it's bug reports, feature requests, or code contributions, we appreciate your help.
-
-### How to Contribute
-
-1. Fork this repository
-2. Create a feature branch (`git checkout -b feature/amazing-feature`)
-3. Commit your changes (`git commit -m 'Add some amazing feature'`)
-4. Push to the branch (`git push origin feature/amazing-feature`)
-5. Open a Pull Request
-
-For bugs or feature requests, please use [GitHub Issues](https://github.com/kez-lab/Compose-DateTimePicker/issues).
-
----
-
-## π Project Structure
-
-```text
-Compose-DateTimePicker/
-βββ datetimepicker/ # Library module
-β βββ src/
-β βββ commonMain/ # Shared code
-β β βββ kotlin/com/kez/picker/
-β β βββ date/ # Date pickers (YearMonthPicker)
-β β βββ time/ # Time pickers (TimePicker)
-β β βββ util/ # Utilities (currentHour, currentDate, etc.)
-β βββ androidMain/ # Android platform implementation
-β βββ iosMain/ # iOS platform implementation
-β βββ desktopMain/ # Desktop (JVM) platform implementation
-β βββ jsMain/ # Web (JS) platform implementation
-βββ sample/ # Sample application
- βββ src/
- βββ commonMain/ # Shared sample code
- βββ androidMain/ # Android entry point
- βββ iosMain/ # iOS entry point
- βββ jvmMain/ # Desktop entry point
- βββ jsMain/ # Web entry point
-```
+### YearMonthPicker
----
+| Parameter | Description | Default |
+| :--- | :--- | :--- |
+| `state` | The state object to control the picker. | `rememberYearMonthPickerState()` |
+| `startLocalDate` | The initial date to set the picker to. | `currentDate` |
+| `yearItems` | List of years available for selection. | `1900..2100` |
+| `monthItems` | List of months available for selection. | `1..12` |
+| `visibleItemsCount` | Number of items visible in the list. | `3` |
-## π License
+## License
```
Copyright 2024 KEZ Lab
@@ -402,11 +190,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
-
----
-
-## π Acknowledgements
-
-Special thanks to all contributors and the Compose Multiplatform community.
-
-If you find this library helpful, please consider giving it a βοΈ on GitHub!
diff --git a/README_KO.md b/README_KO.md
new file mode 100644
index 0000000..3b13865
--- /dev/null
+++ b/README_KO.md
@@ -0,0 +1,192 @@
+# Compose DateTimePicker
+
+[](./README.md)
+
+Compose Multiplatformμ μν λ²μ©μ μ΄κ³ 컀μ€ν°λ§μ΄μ§ κ°λ₯ν λ μ§ λ° μκ° μ ν λΌμ΄λΈλ¬λ¦¬μ
λλ€.
+Android, iOS, Desktop (JVM), Web (Wasm) λ± λ€μν νλ«νΌμμ μΌκ΄λ UI μ»΄ν¬λνΈλ₯Ό μ 곡ν©λλ€.
+
+## μ£Όμ κΈ°λ₯
+
+* **λ©ν°νλ«νΌ μ§μ**: Android, iOS, Desktop (JVM), Web (Wasm) νκ²½μ μ§μνλ©° μνν ν΅ν©μ΄ κ°λ₯ν©λλ€.
+* **TimePicker**: 12μκ°(μ€μ /μ€ν) λ° 24μκ° νμμ λͺ¨λ μ§μν©λλ€.
+* **YearMonthPicker**: λ
λμ μμ μ νν μ μλ μ μ© μ»΄ν¬λνΈλ₯Ό μ 곡ν©λλ€.
+* **컀μ€ν°λ§μ΄μ§**: 컀μ€ν
μμ΄ν
λ λλ§, μ€νμΌλ§, κ΅¬μ± λ³κ²½μ΄ κ°λ₯ν μ μ°ν APIλ₯Ό μ 곡ν©λλ€.
+* **μν κ΄λ¦¬**: `rememberTimePickerState` λ° `rememberYearMonthPickerState`λ₯Ό ν΅ν΄ κ°νΈνκ² μνλ₯Ό κ΄λ¦¬ν μ μμ΅λλ€.
+* **μ κ·Όμ±**: μ€ν¬λ¦° 리λ λ° λ΄λΉκ²μ΄μ
μ§μ λ± μ κ·Όμ±μ κ³ λ €νμ¬ μ€κ³λμμ΅λλ€.
+
+## μ€μΉ λ°©λ²
+
+λ²μ μΉ΄νλ‘κ·Έ λλ λΉλ νμΌμ μμ‘΄μ±μ μΆκ°νμ¬ μ¬μ©ν μ μμ΅λλ€.
+
+### λ²μ μΉ΄νλ‘κ·Έ (libs.versions.toml)
+
+```toml
+[versions]
+composeDateTimePicker = "0.4.0"
+
+[libraries]
+compose-date-time-picker = { module = "io.github.kez-lab:compose-date-time-picker", version.ref = "composeDateTimePicker" }
+```
+
+### Gradle (build.gradle.kts)
+
+```kotlin
+dependencies {
+ implementation("io.github.kez-lab:compose-date-time-picker:0.4.0")
+}
+```
+
+## μ¬μ©λ²
+
+### TimePicker
+
+μκ° μ νμ μν΄ `TimePicker`λ₯Ό μ¬μ©ν©λλ€. 12μκ° λ° 24μκ° νμμ μ§μν©λλ€.
+
+#### 1. 24μκ° νμ
+
+```kotlin
+import androidx.compose.runtime.Composable
+import com.kez.picker.time.TimePicker
+import com.kez.picker.rememberTimePickerState
+import com.kez.picker.util.TimeFormat
+import com.kez.picker.util.currentHour
+import com.kez.picker.util.currentMinute
+
+@Composable
+fun TimePicker24hExample() {
+ val state = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ timeFormat = TimeFormat.HOUR_24
+ )
+
+ TimePicker(
+ state = state
+ )
+}
+```
+
+#### 2. 12μκ° νμ (μ€μ /μ€ν)
+
+```kotlin
+import androidx.compose.runtime.Composable
+import com.kez.picker.time.TimePicker
+import com.kez.picker.rememberTimePickerState
+import com.kez.picker.util.TimeFormat
+import com.kez.picker.util.TimePeriod
+import com.kez.picker.util.currentHour
+import com.kez.picker.util.currentMinute
+
+@Composable
+fun TimePicker12hExample() {
+ // 12μκ° νμ λ³νμ μ΄μ state λ΄λΆμμ μ²λ¦¬λ©λλ€.
+ val state = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ timeFormat = TimeFormat.HOUR_12
+ )
+
+ TimePicker(
+ state = state
+ )
+}
+```
+
+### YearMonthPicker
+
+νΉμ μ°λμ μμ μ νν λ `YearMonthPicker`λ₯Ό μ¬μ©ν©λλ€.
+
+```kotlin
+import androidx.compose.runtime.Composable
+import com.kez.picker.date.YearMonthPicker
+import com.kez.picker.rememberYearMonthPickerState
+import com.kez.picker.util.currentDate
+
+@Composable
+fun YearMonthPickerExample() {
+ val state = rememberYearMonthPickerState(
+ initialYear = currentDate.year,
+ initialMonth = currentDate.monthNumber
+ )
+
+ YearMonthPicker(
+ state = state
+ )
+}
+```
+
+### BottomSheet ν΅ν©
+
+Picker μ»΄ν¬λνΈλ `ModalBottomSheet`λ λ€λ₯Έ λ€μ΄μΌλ‘κ·Έ μ»΄ν¬λνΈ λ΄μμλ μννκ² μλν©λλ€.
+
+```kotlin
+import androidx.compose.material3.*
+import androidx.compose.runtime.*
+import com.kez.picker.time.TimePicker
+import com.kez.picker.rememberTimePickerState
+import kotlinx.coroutines.launch
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun BottomSheetPickerExample() {
+ var showBottomSheet by remember { mutableStateOf(false) }
+ val sheetState = rememberModalBottomSheetState()
+ val state = rememberTimePickerState()
+ val scope = rememberCoroutineScope()
+
+ Button(onClick = { showBottomSheet = true }) {
+ Text("μκ° μ ν")
+ }
+
+ if (showBottomSheet) {
+ ModalBottomSheet(
+ onDismissRequest = { showBottomSheet = false },
+ sheetState = sheetState
+ ) {
+ TimePicker(state = state)
+ // νμΈ λ²νΌ λ‘μ§ λ± μΆκ° κ°λ₯
+ }
+ }
+}
+```
+
+## API λ νΌλ°μ€
+
+### TimePicker
+
+| νλΌλ―Έν° | μ€λͺ
| κΈ°λ³Έκ° |
+| :--- | :--- | :--- |
+| `state` | Pickerλ₯Ό μ μ΄νκΈ° μν μν κ°μ²΄μ
λλ€. | `rememberTimePickerState()` |
+| `startTime` | Pickerμ μ€μ λ μ΄κΈ° μκ°μ
λλ€. | `currentDateTime` |
+| `visibleItemsCount` | 리μ€νΈμ νμλ μμ΄ν
μ κ°μμ
λλ€. | `3` |
+| `textStyle` | μ νλμ§ μμ μμ΄ν
μ ν
μ€νΈ μ€νμΌμ
λλ€. | `16.sp` |
+| `selectedTextStyle` | μ νλ μμ΄ν
μ ν
μ€νΈ μ€νμΌμ
λλ€. | `22.sp` |
+| `dividerColor` | ꡬλΆμ μ μμμ
λλ€. | `LocalContentColor.current` |
+
+### YearMonthPicker
+
+| νλΌλ―Έν° | μ€λͺ
| κΈ°λ³Έκ° |
+| :--- | :--- | :--- |
+| `state` | Pickerλ₯Ό μ μ΄νκΈ° μν μν κ°μ²΄μ
λλ€. | `rememberYearMonthPickerState()` |
+| `startLocalDate` | Pickerμ μ€μ λ μ΄κΈ° λ μ§μ
λλ€. | `currentDate` |
+| `yearItems` | μ ν κ°λ₯ν μ°λ λͺ©λ‘μ
λλ€. | `1900..2100` |
+| `monthItems` | μ ν κ°λ₯ν μ λͺ©λ‘μ
λλ€. | `1..12` |
+| `visibleItemsCount` | 리μ€νΈμ νμλ μμ΄ν
μ κ°μμ
λλ€. | `3` |
+
+## λΌμ΄μ μ€
+
+```
+Copyright 2024 KEZ Lab
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+```
diff --git a/datetimepicker/src/commonMain/kotlin/com/kez/picker/Picker.kt b/datetimepicker/src/commonMain/kotlin/com/kez/picker/Picker.kt
index d6d8e06..f751435 100644
--- a/datetimepicker/src/commonMain/kotlin/com/kez/picker/Picker.kt
+++ b/datetimepicker/src/commonMain/kotlin/com/kez/picker/Picker.kt
@@ -75,8 +75,8 @@ import kotlin.math.abs
fun Picker(
items: List,
state: PickerState,
- startIndex: Int = 0,
modifier: Modifier = Modifier,
+ startIndex: Int = 0,
visibleItemsCount: Int = 3,
textStyle: TextStyle = LocalTextStyle.current,
selectedTextStyle: TextStyle = LocalTextStyle.current,
@@ -94,7 +94,8 @@ fun Picker(
dividerThickness: Dp = 1.dp,
dividerShape: Shape = RoundedCornerShape(10.dp),
isDividerVisible: Boolean = true,
- isInfinity: Boolean = true
+ isInfinity: Boolean = true,
+ content: @Composable ((T) -> Unit)? = null
) {
val density = LocalDensity.current
val visibleItemsMiddle = remember { visibleItemsCount / 2 }
@@ -205,14 +206,14 @@ fun Picker(
}
}
- val currentItemText = getItem(index)?.toString().orEmpty()
-
+ val item = getItem(index)
+
Box(
modifier = Modifier
.height(itemHeight)
.fillMaxWidth()
.clickable(
- enabled = getItem(index) != null,
+ enabled = item != null,
role = Role.Button,
indication = null,
interactionSource = remember { MutableInteractionSource() },
@@ -230,30 +231,35 @@ fun Picker(
.padding(itemPadding),
contentAlignment = Alignment.Center
) {
- Text(
- text = currentItemText,
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- style = textStyle.copy(
- fontSize = lerp(
- selectedTextStyle.fontSize,
- textStyle.fontSize,
- fraction
- ),
- color = lerp(
- selectedTextStyle.color,
- textStyle.color,
- fraction
- ),
- ),
- textAlign = TextAlign.Center
- )
+ if (item != null) {
+ if (content != null) {
+ content(item)
+ } else {
+ Text(
+ text = item.toString(),
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ style = textStyle.copy(
+ fontSize = lerp(
+ selectedTextStyle.fontSize,
+ textStyle.fontSize,
+ fraction
+ ),
+ color = lerp(
+ selectedTextStyle.color,
+ textStyle.color,
+ fraction
+ ),
+ ),
+ textAlign = TextAlign.Center
+ )
+ }
+ }
}
}
}
}
}
-
/**
* Apply a fading edge effect to a modifier.
*
diff --git a/datetimepicker/src/commonMain/kotlin/com/kez/picker/PickerState.kt b/datetimepicker/src/commonMain/kotlin/com/kez/picker/PickerState.kt
index ca6206d..8b316d7 100644
--- a/datetimepicker/src/commonMain/kotlin/com/kez/picker/PickerState.kt
+++ b/datetimepicker/src/commonMain/kotlin/com/kez/picker/PickerState.kt
@@ -1,14 +1,21 @@
package com.kez.picker
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
+import com.kez.picker.util.TimeFormat
+import com.kez.picker.util.TimePeriod
+import com.kez.picker.util.currentDate
+import com.kez.picker.util.currentHour
+import com.kez.picker.util.currentMinute
+import kotlinx.datetime.number
/**
* Remember a [PickerState] with the given initial item.
- *
+ *
* @param initialItem The initial selected item.
* @return A [PickerState] with the given initial item.
*/
@@ -20,6 +27,7 @@ fun rememberPickerState(initialItem: T) = remember { PickerState(initialItem
*
* @param initialItem The initial selected item.
*/
+@Stable
class PickerState(
initialItem: T
) {
@@ -27,4 +35,110 @@ class PickerState(
* The currently selected item.
*/
var selectedItem by mutableStateOf(initialItem)
-}
\ No newline at end of file
+}
+
+/**
+ * Creates and remembers a [YearMonthPickerState].
+ *
+ * @param initialYear The initial year to be selected. Defaults to the current year.
+ * @param initialMonth The initial month to be selected. Defaults to the current month.
+ * @return A [YearMonthPickerState] initialized with the given year and month.
+ */
+@Composable
+fun rememberYearMonthPickerState(
+ initialYear: Int = currentDate.year,
+ initialMonth: Int = currentDate.month.number
+): YearMonthPickerState {
+ return remember(initialYear, initialMonth) {
+ YearMonthPickerState(initialYear, initialMonth)
+ }
+}
+
+/**
+ * State holder for the [com.kez.picker.date.YearMonthPicker].
+ *
+ * Manages the state of the year and month pickers.
+ *
+ * @param initialYear The initial year to be selected.
+ * @param initialMonth The initial month to be selected.
+ */
+@Stable
+class YearMonthPickerState(
+ initialYear: Int,
+ initialMonth: Int
+) {
+ val yearState = PickerState(initialYear)
+ val monthState = PickerState(initialMonth)
+
+ val selectedYear: Int
+ get() = yearState.selectedItem
+
+ val selectedMonth: Int
+ get() = monthState.selectedItem
+}
+
+/**
+ * Creates and remembers a [TimePickerState].
+ *
+ * @param initialHour The initial hour to be selected. Defaults to the current hour.
+ * If [timeFormat] is [TimeFormat.HOUR_12], this value is automatically adjusted to the 12-hour format (1-12).
+ * @param initialMinute The initial minute to be selected. Defaults to the current minute.
+ * @param initialPeriod The initial period (AM/PM) to be selected. Defaults to the current period based on the current hour.
+ * @param timeFormat The time format (12-hour or 24-hour). Defaults to [TimeFormat.HOUR_24].
+ * @return A [TimePickerState] initialized with the given time values.
+ */
+@Composable
+fun rememberTimePickerState(
+ initialHour: Int = currentHour,
+ initialMinute: Int = currentMinute,
+ initialPeriod: TimePeriod = if (initialHour >= 12) TimePeriod.PM else TimePeriod.AM,
+ timeFormat: TimeFormat = TimeFormat.HOUR_24
+): TimePickerState {
+ val adjustedHour = remember(initialHour, timeFormat) {
+ if (timeFormat == TimeFormat.HOUR_12) {
+ val h = initialHour % 12
+ if (h == 0) 12 else h
+ } else {
+ initialHour
+ }
+ }
+ return remember(adjustedHour, initialMinute, initialPeriod, timeFormat) {
+ TimePickerState(
+ initialHour = adjustedHour,
+ initialMinute = initialMinute,
+ initialPeriod = initialPeriod,
+ timeFormat = timeFormat,
+ )
+ }
+}
+
+/**
+ * State holder for the [TimePicker].
+ *
+ * Manages the state of the hour, minute, and period (AM/PM) pickers.
+ *
+ * @param initialHour The initial hour to be selected.
+ * @param initialMinute The initial minute to be selected.
+ * @param initialPeriod The initial period (AM/PM) to be selected.
+ * @param timeFormat The time format (12-hour or 24-hour).
+ */
+@Stable
+class TimePickerState(
+ initialHour: Int,
+ initialMinute: Int,
+ initialPeriod: TimePeriod,
+ val timeFormat: TimeFormat
+) {
+ val hourState = PickerState(initialHour)
+ val minuteState = PickerState(initialMinute)
+ val periodState = PickerState(initialPeriod)
+
+ val selectedHour: Int
+ get() = hourState.selectedItem
+
+ val selectedMinute: Int
+ get() = minuteState.selectedItem
+
+ val selectedPeriod: TimePeriod
+ get() = periodState.selectedItem
+}
\ No newline at end of file
diff --git a/datetimepicker/src/commonMain/kotlin/com/kez/picker/date/YearMonthPicker.kt b/datetimepicker/src/commonMain/kotlin/com/kez/picker/date/YearMonthPicker.kt
index 58aa2d8..07ec07d 100644
--- a/datetimepicker/src/commonMain/kotlin/com/kez/picker/date/YearMonthPicker.kt
+++ b/datetimepicker/src/commonMain/kotlin/com/kez/picker/date/YearMonthPicker.kt
@@ -21,8 +21,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.kez.picker.Picker
-import com.kez.picker.PickerState
-import com.kez.picker.rememberPickerState
+import com.kez.picker.YearMonthPickerState
+import com.kez.picker.rememberYearMonthPickerState
import com.kez.picker.util.MONTH_RANGE
import com.kez.picker.util.YEAR_RANGE
import com.kez.picker.util.currentDate
@@ -58,8 +58,7 @@ import kotlinx.datetime.number
fun YearMonthPicker(
modifier: Modifier = Modifier,
pickerModifier: Modifier = Modifier,
- yearPickerState: PickerState = rememberPickerState(currentDate.year),
- monthPickerState: PickerState = rememberPickerState(currentDate.month.number),
+ state: YearMonthPickerState = rememberYearMonthPickerState(),
startLocalDate: LocalDate = currentDate,
yearItems: List = YEAR_RANGE,
monthItems: List = MONTH_RANGE,
@@ -104,7 +103,7 @@ fun YearMonthPicker(
),
) {
Picker(
- state = yearPickerState,
+ state = state.yearState,
modifier = pickerModifier.weight(1f),
items = yearItems,
startIndex = yearStartIndex,
@@ -123,7 +122,7 @@ fun YearMonthPicker(
isDividerVisible = isDividerVisible,
)
Picker(
- state = monthPickerState,
+ state = state.monthState,
items = monthItems,
startIndex = monthStartIndex,
visibleItemsCount = visibleItemsCount,
diff --git a/datetimepicker/src/commonMain/kotlin/com/kez/picker/time/TimePicker.kt b/datetimepicker/src/commonMain/kotlin/com/kez/picker/time/TimePicker.kt
index 4a2d7de..75a00ec 100644
--- a/datetimepicker/src/commonMain/kotlin/com/kez/picker/time/TimePicker.kt
+++ b/datetimepicker/src/commonMain/kotlin/com/kez/picker/time/TimePicker.kt
@@ -23,15 +23,14 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.kez.picker.Picker
-import com.kez.picker.PickerState
+import com.kez.picker.TimePickerState
+import com.kez.picker.rememberTimePickerState
import com.kez.picker.util.HOUR12_RANGE
import com.kez.picker.util.HOUR24_RANGE
import com.kez.picker.util.MINUTE_RANGE
import com.kez.picker.util.TimeFormat
import com.kez.picker.util.TimePeriod
import com.kez.picker.util.currentDateTime
-import com.kez.picker.util.currentHour
-import com.kez.picker.util.currentMinute
import kotlinx.datetime.LocalDateTime
/**
@@ -39,10 +38,7 @@ import kotlinx.datetime.LocalDateTime
*
* @param modifier The modifier to be applied to the component.
* @param pickerModifier The modifier to be applied to each picker.
- * @param minutePickerState The state for the minute picker.
- * @param hourPickerState The state for the hour picker.
- * @param periodPickerState The state for the AM/PM period picker.
- * @param timeFormat The time format (12-hour or 24-hour).
+ * @param state The state object to control the picker.
* @param startTime The initial time to display.
* @param minuteItems The list of minute values to display.
* @param hourItems The list of hour values to display.
@@ -66,13 +62,10 @@ import kotlinx.datetime.LocalDateTime
fun TimePicker(
modifier: Modifier = Modifier,
pickerModifier: Modifier = Modifier,
- minutePickerState: PickerState = remember { PickerState(currentMinute) },
- hourPickerState: PickerState = remember { PickerState(currentHour) },
- periodPickerState: PickerState = remember { PickerState(TimePeriod.AM) },
- timeFormat: TimeFormat = TimeFormat.HOUR_24,
+ state: TimePickerState = rememberTimePickerState(),
startTime: LocalDateTime = currentDateTime,
minuteItems: List = MINUTE_RANGE,
- hourItems: List = when (timeFormat) {
+ hourItems: List = when (state.timeFormat) {
TimeFormat.HOUR_12 -> HOUR12_RANGE
TimeFormat.HOUR_24 -> HOUR24_RANGE
},
@@ -108,7 +101,7 @@ fun TimePicker(
}
val hourStartIndex = remember {
- val startHour = when (timeFormat) {
+ val startHour = when (state.timeFormat) {
TimeFormat.HOUR_12 -> {
val hour = startTime.hour % 12
if (hour == 0) 12 else hour
@@ -129,9 +122,9 @@ fun TimePicker(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
- if (timeFormat == TimeFormat.HOUR_12) {
+ if (state.timeFormat == TimeFormat.HOUR_12) {
Picker(
- state = periodPickerState,
+ state = state.periodState,
items = periodItems,
visibleItemsCount = visibleItemsCount,
modifier = pickerModifier.weight(1f),
@@ -153,7 +146,7 @@ fun TimePicker(
Spacer(modifier = Modifier.width(spacingBetweenPickers))
}
Picker(
- state = hourPickerState,
+ state = state.hourState,
modifier = pickerModifier.weight(1f),
items = hourItems,
startIndex = hourStartIndex,
@@ -173,7 +166,7 @@ fun TimePicker(
)
Spacer(modifier = Modifier.width(spacingBetweenPickers))
Picker(
- state = minutePickerState,
+ state = state.minuteState,
items = minuteItems,
startIndex = minuteStartIndex,
visibleItemsCount = visibleItemsCount,
@@ -200,7 +193,7 @@ fun TimePicker(
@Composable
fun TimePickerPreview24Hour() {
TimePicker(
- timeFormat = TimeFormat.HOUR_24
+ state = rememberTimePickerState(timeFormat = TimeFormat.HOUR_24)
)
}
@@ -208,7 +201,7 @@ fun TimePickerPreview24Hour() {
@Composable
fun TimePickerPreview12Hour() {
TimePicker(
- timeFormat = TimeFormat.HOUR_12
+ state = rememberTimePickerState(timeFormat = TimeFormat.HOUR_12)
)
}
@@ -216,7 +209,7 @@ fun TimePickerPreview12Hour() {
@Composable
fun TimePickerNoDividerPreview() {
TimePicker(
- timeFormat = TimeFormat.HOUR_24,
+ state = rememberTimePickerState(timeFormat = TimeFormat.HOUR_24),
isDividerVisible = false
)
}
@@ -225,7 +218,7 @@ fun TimePickerNoDividerPreview() {
@Composable
fun TimePickerCustomColorsPreview() {
TimePicker(
- timeFormat = TimeFormat.HOUR_12,
+ state = rememberTimePickerState(timeFormat = TimeFormat.HOUR_12),
textStyle = TextStyle(fontSize = 16.sp, color = Color.Gray),
selectedTextStyle = TextStyle(fontSize = 22.sp, color = Color(0xFF6200EE)),
dividerColor = Color(0xFF6200EE)
@@ -236,7 +229,7 @@ fun TimePickerCustomColorsPreview() {
@Composable
fun TimePickerLargeTextPreview() {
TimePicker(
- timeFormat = TimeFormat.HOUR_24,
+ state = rememberTimePickerState(timeFormat = TimeFormat.HOUR_24),
textStyle = TextStyle(fontSize = 20.sp),
selectedTextStyle = TextStyle(fontSize = 28.sp),
visibleItemsCount = 5
diff --git a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BackgroundStylePickerScreen.kt b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BackgroundStylePickerScreen.kt
index 732dfcf..d241513 100644
--- a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BackgroundStylePickerScreen.kt
+++ b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BackgroundStylePickerScreen.kt
@@ -31,7 +31,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.kez.picker.date.YearMonthPicker
-import com.kez.picker.rememberPickerState
+import com.kez.picker.rememberTimePickerState
+import com.kez.picker.rememberYearMonthPickerState
import com.kez.picker.sample.formatTime12
import com.kez.picker.sample.getMonthName
import com.kez.picker.time.TimePicker
@@ -49,19 +50,23 @@ import kotlinx.datetime.number
internal fun BackgroundStylePickerScreen(
onBackPressed: () -> Unit = {},
) {
- val yearState = rememberPickerState(currentDate.year)
- val monthState = rememberPickerState(currentDate.month.number)
- val hourState =
- rememberPickerState(if (currentHour > 12) currentHour - 12 else if (currentHour == 0) 12 else currentHour)
- val minuteState = rememberPickerState(currentMinute)
- val periodState = rememberPickerState(if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM)
+ val yearMonthState = rememberYearMonthPickerState(
+ initialYear = currentDate.year,
+ initialMonth = currentDate.monthNumber
+ )
+ val timeState = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ initialPeriod = if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM,
+ timeFormat = TimeFormat.HOUR_12
+ )
- val selectedDateText = remember(yearState.selectedItem, monthState.selectedItem) {
- "${yearState.selectedItem}λ
${getMonthName(monthState.selectedItem)}"
+ val selectedDateText = remember(yearMonthState.selectedYear, yearMonthState.selectedMonth) {
+ "${yearMonthState.selectedYear}λ
${getMonthName(yearMonthState.selectedMonth)}"
}
val selectedTimeText =
- remember(hourState.selectedItem, minuteState.selectedItem, periodState.selectedItem) {
- formatTime12(hourState.selectedItem, minuteState.selectedItem, periodState.selectedItem)
+ remember(timeState.selectedHour, timeState.selectedMinute, timeState.selectedPeriod) {
+ formatTime12(timeState.selectedHour, timeState.selectedMinute, timeState.selectedPeriod)
}
Scaffold(
@@ -118,8 +123,7 @@ internal fun BackgroundStylePickerScreen(
horizontalAlignment = Alignment.CenterHorizontally
) {
YearMonthPicker(
- yearPickerState = yearState,
- monthPickerState = monthState,
+ state = yearMonthState,
textStyle = TextStyle(
fontSize = 18.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
@@ -152,10 +156,7 @@ internal fun BackgroundStylePickerScreen(
horizontalAlignment = Alignment.CenterHorizontally
) {
TimePicker(
- hourPickerState = hourState,
- minutePickerState = minuteState,
- periodPickerState = periodState,
- timeFormat = TimeFormat.HOUR_12,
+ state = timeState,
textStyle = TextStyle(
fontSize = 18.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
diff --git a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BottomSheetSampleScreen.kt b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BottomSheetSampleScreen.kt
index 9a1e22c..037b2fd 100644
--- a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BottomSheetSampleScreen.kt
+++ b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/BottomSheetSampleScreen.kt
@@ -38,7 +38,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.kez.picker.date.YearMonthPicker
-import com.kez.picker.rememberPickerState
+import com.kez.picker.rememberTimePickerState
+import com.kez.picker.rememberYearMonthPickerState
import com.kez.picker.sample.formatTime12
import com.kez.picker.sample.getMonthName
import com.kez.picker.time.TimePicker
@@ -60,12 +61,16 @@ internal fun BottomSheetSampleScreen(
onBackPressed: () -> Unit = {},
) {
// Date/time state management
- val yearState = rememberPickerState(currentDate.year)
- val monthState = rememberPickerState(currentDate.month.number)
- val hourState =
- rememberPickerState(if (currentHour > 12) currentHour - 12 else if (currentHour == 0) 12 else currentHour)
- val minuteState = rememberPickerState(currentMinute)
- val periodState = rememberPickerState(if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM)
+ val yearMonthState = rememberYearMonthPickerState(
+ initialYear = currentDate.year,
+ initialMonth = currentDate.monthNumber
+ )
+ val timeState = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ initialPeriod = if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM,
+ timeFormat = TimeFormat.HOUR_12
+ )
// Selected date/time text
var selectedDateText by remember {
@@ -74,9 +79,9 @@ internal fun BottomSheetSampleScreen(
var selectedTimeText by remember {
mutableStateOf(
formatTime12(
- hourState.selectedItem,
- minuteState.selectedItem,
- periodState.selectedItem
+ timeState.selectedHour,
+ timeState.selectedMinute,
+ timeState.selectedPeriod
)
)
}
@@ -240,8 +245,7 @@ internal fun BottomSheetSampleScreen(
contentAlignment = Alignment.Center
) {
YearMonthPicker(
- yearPickerState = yearState,
- monthPickerState = monthState,
+ state = yearMonthState,
textStyle = TextStyle(
fontSize = 18.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
@@ -261,7 +265,7 @@ internal fun BottomSheetSampleScreen(
onClick = {
// Update selected date
selectedDateText =
- "${yearState.selectedItem}λ
${getMonthName(monthState.selectedItem)}"
+ "${yearMonthState.selectedYear}λ
${getMonthName(yearMonthState.selectedMonth)}"
scope.launch {
dateSheetState.hide()
showDateBottomSheet = false
@@ -305,10 +309,7 @@ internal fun BottomSheetSampleScreen(
contentAlignment = Alignment.Center
) {
TimePicker(
- hourPickerState = hourState,
- minutePickerState = minuteState,
- periodPickerState = periodState,
- timeFormat = TimeFormat.HOUR_12,
+ state = timeState,
textStyle = TextStyle(
fontSize = 18.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
@@ -328,9 +329,9 @@ internal fun BottomSheetSampleScreen(
onClick = {
// Update selected time
selectedTimeText = formatTime12(
- hourState.selectedItem,
- minuteState.selectedItem,
- periodState.selectedItem
+ timeState.selectedHour,
+ timeState.selectedMinute,
+ timeState.selectedPeriod
)
scope.launch {
timeSheetState.hide()
diff --git a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/DatePickerSampleScreen.kt b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/DatePickerSampleScreen.kt
index 78756e2..5d79a23 100644
--- a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/DatePickerSampleScreen.kt
+++ b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/DatePickerSampleScreen.kt
@@ -30,7 +30,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.kez.picker.date.YearMonthPicker
-import com.kez.picker.rememberPickerState
+import com.kez.picker.rememberYearMonthPickerState
import com.kez.picker.sample.getMonthName
import com.kez.picker.util.currentDate
import compose.icons.FeatherIcons
@@ -43,13 +43,15 @@ import kotlinx.datetime.number
internal fun DatePickerSampleScreen(
onBackPressed: () -> Unit = {},
) {
- val yearState = rememberPickerState(currentDate.year)
- val monthState = rememberPickerState(currentDate.month.number)
+ val state = rememberYearMonthPickerState(
+ initialYear = currentDate.year,
+ initialMonth = currentDate.monthNumber
+ )
// Calculate selected date text
val selectedDateText by remember {
derivedStateOf {
- "${yearState.selectedItem}λ
${getMonthName(monthState.selectedItem)}"
+ "${state.selectedYear}λ
${getMonthName(state.selectedMonth)}"
}
}
@@ -105,8 +107,7 @@ internal fun DatePickerSampleScreen(
YearMonthPicker(
modifier = Modifier.padding(horizontal = 12.dp),
- yearPickerState = yearState,
- monthPickerState = monthState
+ state = state
)
// TODO: Add day selection capability
diff --git a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/IntegratedPickerScreen.kt b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/IntegratedPickerScreen.kt
index ffdf091..dfda8f7 100644
--- a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/IntegratedPickerScreen.kt
+++ b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/IntegratedPickerScreen.kt
@@ -49,9 +49,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import androidx.navigation.compose.rememberNavController
import com.kez.picker.date.YearMonthPicker
-import com.kez.picker.rememberPickerState
+import com.kez.picker.rememberTimePickerState
+import com.kez.picker.rememberYearMonthPickerState
import com.kez.picker.sample.formatTime12
import com.kez.picker.sample.getMonthName
import com.kez.picker.time.TimePicker
@@ -64,27 +64,32 @@ import compose.icons.FeatherIcons
import compose.icons.feathericons.ArrowLeft
import compose.icons.feathericons.Calendar
import compose.icons.feathericons.Clock
+import kotlinx.datetime.number
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun IntegratedPickerScreen(
onBackPressed: () -> Unit = {},
) {
- val yearState = rememberPickerState(currentDate.year)
- val monthState = rememberPickerState(currentDate.monthNumber)
- val hourState =
- rememberPickerState(if (currentHour > 12) currentHour - 12 else if (currentHour == 0) 12 else currentHour)
- val minuteState = rememberPickerState(currentMinute)
- val periodState = rememberPickerState(if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM)
+ val yearMonthState = rememberYearMonthPickerState(
+ initialYear = currentDate.year,
+ initialMonth = currentDate.month.number
+ )
+ val timeState = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ initialPeriod = if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM,
+ timeFormat = TimeFormat.HOUR_12
+ )
var selectedTabIndex by remember { mutableIntStateOf(0) }
- val selectedDateText = remember(yearState.selectedItem, monthState.selectedItem) {
- "${yearState.selectedItem}λ
${getMonthName(monthState.selectedItem)}"
+ val selectedDateText = remember(yearMonthState.selectedYear, yearMonthState.selectedMonth) {
+ "${yearMonthState.selectedYear}λ
${getMonthName(yearMonthState.selectedMonth)}"
}
val selectedTimeText =
- remember(hourState.selectedItem, minuteState.selectedItem, periodState.selectedItem) {
- formatTime12(hourState.selectedItem, minuteState.selectedItem, periodState.selectedItem)
+ remember(timeState.selectedHour, timeState.selectedMinute, timeState.selectedPeriod) {
+ formatTime12(timeState.selectedHour, timeState.selectedMinute, timeState.selectedPeriod)
}
Scaffold(
@@ -162,8 +167,7 @@ internal fun IntegratedPickerScreen(
) {
if (tabIndex == 0) {
YearMonthPicker(
- yearPickerState = yearState,
- monthPickerState = monthState,
+ state = yearMonthState,
textStyle = TextStyle(
fontSize = 18.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
@@ -177,10 +181,7 @@ internal fun IntegratedPickerScreen(
)
} else {
TimePicker(
- hourPickerState = hourState,
- minutePickerState = minuteState,
- periodPickerState = periodState,
- timeFormat = TimeFormat.HOUR_12,
+ state = timeState,
textStyle = TextStyle(
fontSize = 18.sp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
diff --git a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/TimePickerSampleScreen.kt b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/TimePickerSampleScreen.kt
index c505b0b..f0df747 100644
--- a/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/TimePickerSampleScreen.kt
+++ b/sample/src/commonMain/kotlin/com/kez/picker/sample/ui/screen/TimePickerSampleScreen.kt
@@ -34,7 +34,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import com.kez.picker.rememberPickerState
+import com.kez.picker.rememberTimePickerState
import com.kez.picker.time.TimePicker
import com.kez.picker.util.TimeFormat
import com.kez.picker.util.TimePeriod
@@ -54,11 +54,16 @@ internal fun TimePickerSampleScreen(
onBackPressed: () -> Unit = {},
) {
var selectedFormat by remember { mutableIntStateOf(0) }
- val hour12State =
- rememberPickerState(if (currentHour > 12) currentHour - 12 else if (currentHour == 0) 12 else currentHour)
- val hour24State = rememberPickerState(currentHour)
- val minuteState = rememberPickerState(currentMinute)
- val periodState = rememberPickerState(if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM)
+ val timeState12 = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute,
+ initialPeriod = if (currentHour >= 12) TimePeriod.PM else TimePeriod.AM,
+ timeFormat = TimeFormat.HOUR_12
+ )
+ val timeState24 = rememberTimePickerState(
+ initialHour = currentHour,
+ initialMinute = currentMinute
+ )
val ktxTimeFormat12 = LocalTime.Format {
amPmHour(padding = Padding.ZERO)
@@ -77,9 +82,9 @@ internal fun TimePickerSampleScreen(
val selectedTimeText by remember {
derivedStateOf {
if (selectedFormat == 0) {
- val hour12 = hour12State.selectedItem // (1 ~ 12)
- val minute = minuteState.selectedItem
- val isAm = periodState.selectedItem == TimePeriod.AM
+ val hour12 = timeState12.selectedHour // (1 ~ 12)
+ val minute = timeState12.selectedMinute
+ val isAm = timeState12.selectedPeriod == TimePeriod.AM
val hour24 = when {
isAm && hour12 == 12 -> 0 // 12:xx AM (midnight) -> 0
@@ -90,7 +95,7 @@ internal fun TimePickerSampleScreen(
time.format(ktxTimeFormat12)
} else {
- val time = LocalTime(hour24State.selectedItem, minuteState.selectedItem)
+ val time = LocalTime(timeState24.selectedHour, timeState24.selectedMinute)
time.format(ktxTimeFormat24)
}
}
@@ -159,17 +164,12 @@ internal fun TimePickerSampleScreen(
Spacer(modifier = Modifier.height(32.dp))
if (selectedFormat == 0) {
TimePicker(
- hourPickerState = hour12State,
- minutePickerState = minuteState,
- periodPickerState = periodState,
- timeFormat = TimeFormat.HOUR_12
+ state = timeState12
)
} else {
TimePicker(
- hourPickerState = hour24State,
- minutePickerState = minuteState,
- visibleItemsCount = 5,
- timeFormat = TimeFormat.HOUR_24
+ state = timeState24,
+ visibleItemsCount = 5
)
}
}