Skip to content

Stabilize picker format and semantics API - #104

Merged
kez-lab merged 2 commits into
mainfrom
feature/stabilize-picker-api
May 31, 2026
Merged

kez-lab merged 2 commits into
mainfrom
feature/stabilize-picker-api

Conversation

@kez-lab

@kez-lab kez-lab commented May 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Rework picker value text APIs from display/accessibility into format/semantics: value descriptions now live in PickerItemFormat, while PickerSemantics is non-generic and handles labels/actions only.
  • Add accessibility fallback from visible item text, migrate samples/tests/docs, and regenerate Android/Desktop/KLIB ABI dumps.
  • Bound date/year-month year columns by default, memoize validation/selectable list derivation with remember/derivedStateOf, remove dead calculateTime and PickerStyle.verticalAlignment, and move test-only validation overloads into commonTest helpers.
  • Remove the manual picker cache classes, keep the non-default column-order regression coverage, and add a TimePicker fast path so already-valid selections do not call coerceTime() on every item change.
  • Update AGENTS.md with maintainer rules from this review: measure before bespoke performance machinery, test non-standard invalidation logic, align shared invariants, and red-team PRs before review.

Breaking Changes

  • PickerItemText -> PickerItemFormat; *Display -> *Format; PickerAccessibility/*Accessibility -> PickerSemantics/*Semantics.
  • display parameters are now format; accessibility parameters are now semantics.
  • item content description lambdas move from semantics/accessibility factories into format factories.

Validation

  • ./gradlew :datetimepicker:compileKotlinMetadata --no-daemon
  • ./gradlew :datetimepicker:testDebugUnitTest :datetimepicker:assembleDebugAndroidTest :sample:assembleDebugAndroidTest --no-daemon
  • ./gradlew :sample:compileKotlinDesktop :datetimepicker:checkLegacyAbi --no-daemon
  • ./gradlew :datetimepicker:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.kez.picker.PickerFormatAndroidTest --no-daemon
  • ./gradlew :sample:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.kez.picker.sample.SampleAppSmokeAndroidTest#timePickerMenuAction_opensTimePickerSampleAndRendersDefaultTab --no-daemon
  • git diff --check

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced improved item coercion for date/year-month pickers that selects the closest valid selectable item.
    • Added new format/semantics configuration APIs for clearer separation between text formatting and accessibility/semantic labeling.
  • Breaking Changes

    • Replaced display/accessibility parameters with format/semantics across all picker components.
    • Removed calculateTime() utility function and PickerStyle.verticalAlignment configuration.
  • Documentation

    • Updated API documentation and examples to reflect new format/semantics naming conventions.

@coderabbitai

coderabbitai Bot commented May 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR executes a comprehensive API refactoring across the datetime picker library, replacing the "display/accessibility" configuration model with a "format/semantics" model. The changes affect type definitions, composable signatures, validation logic, tests, sample apps, and public API surfaces.

Changes

Picker API Model & Implementation Refactoring

Layer / File(s) Summary
Format/Semantics Type Definitions
datetimepicker/src/commonMain/kotlin/com/kez/picker/PickerFormat.kt, PickerSemantics.kt
New @Immutable data classes PickerItemFormat<T>, TimePickerFormat, DatePickerFormat, YearMonthPickerFormat, PickerSemantics, TimePickerSemantics, DatePickerSemantics, DateRangePickerSemantics, YearMonthPickerSemantics replace old PickerDisplay, PickerAccessibility, and related types.
Core Picker Composable & Defaults Refactoring
datetimepicker/src/commonMain/kotlin/com/kez/picker/Picker.kt, PickerDefaults.kt
Picker composable now accepts format: PickerItemFormat<T> and semantics: PickerSemantics (replacing display/accessibility). PickerDefaults introduces semantics(...), itemFormat(...), timePickerFormat(...), datePickerFormat(...), yearMonthPickerFormat(...), and composite semantics builders. PickerStyle loses verticalAlignment. Helpers renamed to pickerSemanticsDescription(...). Input validation moved into remember(...) block.
Specialized Pickers API Updates
datetimepicker/src/commonMain/kotlin/com/kez/picker/date/DatePicker.kt, TimePicker.kt, YearMonthPicker.kt, DateRangePicker.kt
DatePicker, TimePicker, YearMonthPicker, DateRangePicker all updated to accept format and semantics parameters instead of display/accessibility. Item lists now derived via remember + derivedStateOf. Internal validation overloads simplified.
Picker Items & Validation Logic
datetimepicker/src/commonMain/kotlin/com/kez/picker/PickerItems.kt
DatePickerItems.coerceDate(...) refactored to select closest selectable LocalDate by epoch-day distance. YearMonthPickerItems.coerceYearMonth(...) now throws IllegalArgumentException for out-of-range year/month (was coerced). Validation requirements updated to match new coercion semantics.
Robolectric Test Migration & New Coverage
datetimepicker/src/androidUnitTest/kotlin/com/kez/picker/*.kt
Android instrumentation tests migrated to Robolectric (@RunWith(RobolectricTestRunner::class), @Config(sdk = [35])). All picker tests updated from display/accessibility to format/semantics configuration. New column-order edge-case tests and bounded-edge custom-action tests added for DatePicker and YearMonthPicker. Semantics restoration tests updated.
Unit Test Updates & Helpers
datetimepicker/src/commonTest/kotlin/.../PickerUtilsTest.kt, PickerValidationTestHelpers.kt, *StateTest.kt
Test methods renamed from pickerAccessibilityDescription_* to pickerSemanticsDescription_*. New validation helper functions for TimePickerItems, YearMonthPickerItems, DatePickerItems. Coercion assertions updated to expect stricter range validation (throw instead of coerce).
Sample App Updates
sample/src/commonMain/kotlin/.../\*PickerScreen.kt, SampleAppSmokeAndroidTest.kt
All picker sample screens (TimePicker, DatePicker, DateRange, YearMonth, BackgroundStyle, BottomSheet, Integrated) updated to use PickerDefaults.*Format(...) and PickerDefaults.*Semantics(...) instead of display/accessibility. New TimePicker smoke test added.
ABI/API Surface Updates
datetimepicker/api/android/datetimepicker.api, datetimepicker/api/datetimepicker.klib.api, datetimepicker/api/desktop/datetimepicker.api, datetimepicker/build.gradle.kts, gradle/libs.versions.toml
Public API surfaces updated to reflect removal of *Display and *Accessibility types and introduction of *Format and *Semantics types. PickerStyle signature loses verticalAlignment. Robolectric dependency added to build.
Documentation Updates
README.md, README_KO.md, CHANGELOG.md, AGENTS.md, TimePickerState.kt
README files updated with new format/semantics API examples and parameter table entries. CHANGELOG documents breaking changes, coercion behavior changes, parameter reordering, and renames. AGENTS.md updated with developer guide for new patterns and test strategy. TimePickerState KDoc reworded from "display-hour" to "format-hour" terminology.
Minor Cleanup
.github/workflows/integration-build-test.yml, sample/src/commonMain/kotlin/.../StringUtils.kt
Whitespace corrections in CI workflow and StringUtils.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement

🐰 Whiskers twitching with joy—
Old "display" hops away,
New "format" takes stage,
Semantics dance bright—
Clarity springs forth! 🎨✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/stabilize-picker-api

@kez-lab
kez-lab force-pushed the feature/stabilize-picker-api branch 2 times, most recently from 7d7bf38 to 4a20e15 Compare May 30, 2026 00:09
@kez-lab
kez-lab force-pushed the feature/stabilize-picker-api branch from 4a20e15 to c7f66b0 Compare May 30, 2026 00:12
@kez-lab
kez-lab merged commit f3a3b69 into main May 31, 2026
6 checks passed
@kez-lab
kez-lab deleted the feature/stabilize-picker-api branch May 31, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant