Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 38 additions & 31 deletions .github/workflows/integration-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ permissions:
contents: read

env:
MODULE: ":datetimepicker"
LIBRARY_MODULE: ":datetimepicker"
SAMPLE_MODULE: ":sample"
jobs:

linux-builds:
Expand All @@ -26,14 +27,15 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: gradle/wrapper-validation-action@v2
- uses: gradle/actions/wrapper-validation@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'

- uses: gradle/actions/setup-gradle@v4

# Android Set Up
- name: Set up Android SDK
Expand All @@ -44,39 +46,42 @@ jobs:
if: matrix.target == 'android'
run: |
sdkmanager "platform-tools" \
"platforms;android-34" \
"build-tools;34.0.0" || true
yes | sdkmanager --licenses || true
"platforms;android-36" \
"build-tools;36.0.0"
yes | sdkmanager --licenses

# Android Build/Unit Test
- name: Gradle Build • Android
if: matrix.target == 'android'
uses: gradle/gradle-build-action@v3
with:
arguments: |
${{ env.MODULE }}:clean
${{ env.MODULE }}:assembleRelease
${{ env.MODULE }}:testReleaseUnitTest
run: |
./gradlew \
${{ env.LIBRARY_MODULE }}:clean \
${{ env.LIBRARY_MODULE }}:assembleRelease \
${{ env.LIBRARY_MODULE }}:testReleaseUnitTest \
${{ env.SAMPLE_MODULE }}:assembleDebug \
--no-daemon

# Web(WASM) Build/Test
- name: Gradle Build • Web (WASM)
if: matrix.target == 'wasm'
uses: gradle/gradle-build-action@v3
with:
arguments: |
${{ env.MODULE }}:clean
${{ env.MODULE }}:wasmJsBrowserDistribution
${{ env.MODULE }}:wasmJsTest
run: |
./gradlew \
${{ env.LIBRARY_MODULE }}:clean \
${{ env.LIBRARY_MODULE }}:wasmJsBrowserDistribution \
${{ env.LIBRARY_MODULE }}:wasmJsTest \
${{ env.SAMPLE_MODULE }}:wasmJsBrowserDistribution \
--no-daemon

# Desktop(JVM) Build/Test
- name: Gradle Build • Desktop (JVM)
if: matrix.target == 'desktop'
uses: gradle/gradle-build-action@v3
with:
arguments: |
${{ env.MODULE }}:clean
${{ env.MODULE }}:desktopJar
${{ env.MODULE }}:desktopTest
run: |
./gradlew \
${{ env.LIBRARY_MODULE }}:clean \
${{ env.LIBRARY_MODULE }}:desktopJar \
${{ env.LIBRARY_MODULE }}:desktopTest \
${{ env.SAMPLE_MODULE }}:compileKotlinDesktop \
--no-daemon

ios-build-and-test:
name: macOS • iOS Simulator Test
Expand All @@ -85,14 +90,15 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: gradle/wrapper-validation-action@v2
- uses: gradle/actions/wrapper-validation@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'

- uses: gradle/actions/setup-gradle@v4

- name: Boot iOS Simulator (iPhone 15)
run: |
Expand All @@ -104,8 +110,9 @@ jobs:

# iOS Simulator Unit Test
- name: Gradle Build & Test • iOS
uses: gradle/gradle-build-action@v3
with:
arguments: |
${{ env.MODULE }}:clean
${{ env.MODULE }}:iosSimulatorArm64Test
run: |
./gradlew \
${{ env.LIBRARY_MODULE }}:clean \
${{ env.LIBRARY_MODULE }}:iosSimulatorArm64Test \
${{ env.SAMPLE_MODULE }}:compileKotlinIosSimulatorArm64 \
--no-daemon
89 changes: 71 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ It provides consistent UI components across Android, iOS, Desktop (JVM), and Web

* **Multiplatform Support**: seamless integration for Android, iOS, Desktop (JVM), and Web (Wasm).
* **TimePicker**: Supports both 12-hour (AM/PM) and 24-hour formats.
* **DatePicker**: A complete date picker for selecting year, month, and day with automatic day
validation.
* **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`.
* **State Management**: simplified state handling with `rememberTimePickerState`,
`rememberDatePickerState`, and `rememberYearMonthPickerState`.
* **Accessibility**: Built with accessibility in mind, supporting screen readers and navigation.

## Installation
Expand All @@ -22,7 +25,7 @@ Add the dependency to your version catalog or build file.

```toml
[versions]
composeDateTimePicker = "0.4.0"
composeDateTimePicker = "0.5.0"

[libraries]
compose-date-time-picker = { module = "io.github.kez-lab:compose-date-time-picker", version.ref = "composeDateTimePicker" }
Expand All @@ -32,7 +35,7 @@ compose-date-time-picker = { module = "io.github.kez-lab:compose-date-time-picke

```kotlin
dependencies {
implementation("io.github.kez-lab:compose-date-time-picker:0.4.0")
implementation("io.github.kez-lab:compose-date-time-picker:0.5.0")
}
```

Expand All @@ -55,8 +58,8 @@ import com.kez.picker.util.currentMinute
@Composable
fun TimePicker24hExample() {
val state = rememberTimePickerState(
initialHour = currentHour,
initialMinute = currentMinute,
initialHour = currentHour(),
initialMinute = currentMinute(),
timeFormat = TimeFormat.HOUR_24
)

Expand All @@ -73,16 +76,15 @@ 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() {
// Handling of 12-hour format conversion is now done internally by the state
val state = rememberTimePickerState(
initialHour = currentHour,
initialMinute = currentMinute,
initialHour = currentHour(),
initialMinute = currentMinute(),
timeFormat = TimeFormat.HOUR_12
)

Expand All @@ -92,6 +94,35 @@ fun TimePicker12hExample() {
}
```

### DatePicker

Use `DatePicker` for selecting a complete date (year, month, and day). The component automatically
adjusts the day when the selected month changes (e.g., Feb 30 → Feb 28).

```kotlin
import androidx.compose.runtime.Composable
import com.kez.picker.date.DatePicker
import com.kez.picker.date.rememberDatePickerState
import com.kez.picker.util.currentDate
import com.kez.picker.util.currentMonth

@Composable
fun DatePickerExample() {
val state = rememberDatePickerState(
initialYear = currentDate().year,
initialMonth = currentMonth(),
initialDay = currentDate().day
)

DatePicker(
state = state
)

// Access selected values
// state.selectedYear, state.selectedMonth, state.selectedDay
}
```

### YearMonthPicker

Use `YearMonthPicker` for selecting a specific month in a year.
Expand All @@ -101,12 +132,13 @@ import androidx.compose.runtime.Composable
import com.kez.picker.date.YearMonthPicker
import com.kez.picker.rememberYearMonthPickerState
import com.kez.picker.util.currentDate
import com.kez.picker.util.currentMonth

@Composable
fun YearMonthPickerExample() {
val state = rememberYearMonthPickerState(
initialYear = currentDate.year,
initialMonth = currentDate.monthNumber
initialYear = currentDate().year,
initialMonth = currentMonth()
)

YearMonthPicker(
Expand All @@ -124,15 +156,13 @@ 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("Select Time")
Expand All @@ -157,21 +187,44 @@ fun BottomSheetPickerExample() {
| Parameter | Description | Default |
| :--- | :--- | :--- |
| `state` | The state object to control the picker. | `rememberTimePickerState()` |
| `startTime` | The initial time to set the picker to. | `currentDateTime` |
| `startTime` | Legacy initial time parameter. Prefer setting initial values in `rememberTimePickerState`. | `currentDateTime()` |
| `minuteItems` | Minute values available for selection. | `0..59` |
| `hourItems` | Hour values available for selection. | `0..23` or `1..12` |
| `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` |
| `colors` | Colors for text, selected text, dividers, and selected item background. | `PickerDefaults.colors()` |
| `textStyles` | Text styles for selected and unselected items. | `PickerDefaults.textStyles()` |
| `isDividerVisible` | Whether selection dividers are visible. | `true` |

### DatePicker

| Parameter | Description | Default |
|:--------------------|:----------------------------------------|:----------------------------|
| `state` | The state object to control the picker. | `rememberDatePickerState()` |
| `startLocalDate` | Legacy initial date parameter. Prefer setting initial values in `rememberDatePickerState`. | `currentDate()` |
| `yearItems` | List of years available for selection. | `1000..9999` |
| `monthItems` | List of months available for selection. | `1..12` |
| `visibleItemsCount` | Number of items visible in the list. | `3` |
| `colors` | Colors for text, selected text, dividers, and selected item background. | `PickerDefaults.colors()` |
| `textStyles` | Text styles for selected and unselected items. | `PickerDefaults.textStyles()` |

**DatePickerState Properties:**

- `selectedYear`: The currently selected year.
- `selectedMonth`: The currently selected month (1-12).
- `selectedDay`: The currently selected day (1-31, auto-adjusted based on month).
- `maxDay`: The maximum valid day for the selected year and month.

### 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` |
| `startLocalDate` | Legacy initial date parameter. Prefer setting initial values in `rememberYearMonthPickerState`. | `currentDate()` |
| `yearItems` | List of years available for selection. | `1000..9999` |
| `monthItems` | List of months available for selection. | `1..12` |
| `visibleItemsCount` | Number of items visible in the list. | `3` |
| `colors` | Colors for text, selected text, dividers, and selected item background. | `PickerDefaults.colors()` |
| `textStyles` | Text styles for selected and unselected items. | `PickerDefaults.textStyles()` |

## License

Expand Down
Loading
Loading