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
5 changes: 5 additions & 0 deletions .changeset/hot-feet-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@capawesome-team/capacitor-datetime-picker': minor
---

feat(ios): add `minuteInterval` option
27 changes: 14 additions & 13 deletions packages/datetime-picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,20 @@ Only available on Android and iOS.

#### PresentOptions

| Prop | Type | Description | Default | Since |
| --------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | ----- |
| **`cancelButtonText`** | <code>string</code> | The cancel button text. | <code>'Cancel'</code> | 0.0.1 |
| **`doneButtonText`** | <code>string</code> | The done button text. | <code>'Ok'</code> | 0.0.1 |
| **`format`** | <code>string</code> | The format in which values are received and returned. | <code>'yyyy-MM-dd'T'HH:mm:ss.sss'Z''</code> | 0.0.1 |
| **`locale`** | <code>string</code> | BCP 47 language tag to define the language of the UI. | | 0.0.2 |
| **`max`** | <code>string</code> | The latest date and time to accept. The format of this value must match the value of the `format` parameter. This value must specify a date string later than or equal to the one specified by the `min` attribute. | | 0.0.1 |
| **`min`** | <code>string</code> | The earliest date and time to accept. The format of this value must match the value of the `format` parameter. This value must specify a date string earlier than or equal to the one specified by the `max` attribute. | | 0.0.1 |
| **`mode`** | <code>'date' \| 'time' \| 'datetime'</code> | Whether you want a date or time or datetime picker. | <code>'datetime'</code> | 0.0.1 |
| **`theme`** | <code>'auto' \| 'light' \| 'dark'</code> | Choose the theme that the datetime picker should have. With `auto` the system theme is used. This value overwrites the `theme` configuration value. Only available on Android and iOS. Spinner options only available on Android | | 0.0.1 |
| **`value`** | <code>string</code> | The predefined value when opening the picker. The format of this value must match the value of the `format` parameter. | | 0.0.1 |
| **`androidTimePickerMode`** | <code>'clock' \| 'spinner'</code> | Whether to use the spinner or clock mode for the time picker on Android. This value overwrites the `androidTimePickerMode` configuration value. Only available on Android. | | 5.1.0 |
| **`androidDatePickerMode`** | <code>'spinner' \| 'calendar'</code> | Whether to use the calendar or spinner mode for the date picker on Android. This value overwrites the `androidDatePickerMode` configuration value. Only available on Android. | | 5.1.0 |
| Prop | Type | Description | Default | Since |
| --------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | ----- |
| **`cancelButtonText`** | <code>string</code> | The cancel button text. | <code>'Cancel'</code> | 0.0.1 |
| **`doneButtonText`** | <code>string</code> | The done button text. | <code>'Ok'</code> | 0.0.1 |
| **`format`** | <code>string</code> | The format in which values are received and returned. | <code>'yyyy-MM-dd'T'HH:mm:ss.sss'Z''</code> | 0.0.1 |
| **`locale`** | <code>string</code> | BCP 47 language tag to define the language of the UI. | | 0.0.2 |
| **`max`** | <code>string</code> | The latest date and time to accept. The format of this value must match the value of the `format` parameter. This value must specify a date string later than or equal to the one specified by the `min` attribute. | | 0.0.1 |
| **`min`** | <code>string</code> | The earliest date and time to accept. The format of this value must match the value of the `format` parameter. This value must specify a date string earlier than or equal to the one specified by the `max` attribute. | | 0.0.1 |
| **`mode`** | <code>'date' \| 'time' \| 'datetime'</code> | Whether you want a date or time or datetime picker. | <code>'datetime'</code> | 0.0.1 |
| **`theme`** | <code>'auto' \| 'light' \| 'dark'</code> | Choose the theme that the datetime picker should have. With `auto` the system theme is used. This value overwrites the `theme` configuration value. Only available on Android and iOS. Spinner options only available on Android | | 0.0.1 |
| **`value`** | <code>string</code> | The predefined value when opening the picker. The format of this value must match the value of the `format` parameter. | | 0.0.1 |
| **`androidTimePickerMode`** | <code>'clock' \| 'spinner'</code> | Whether to use the spinner or clock mode for the time picker on Android. This value overwrites the `androidTimePickerMode` configuration value. Only available on Android. | | 5.1.0 |
| **`androidDatePickerMode`** | <code>'spinner' \| 'calendar'</code> | Whether to use the calendar or spinner mode for the date picker on Android. This value overwrites the `androidDatePickerMode` configuration value. Only available on Android. | | 5.1.0 |
| **`minuteInterval`** | <code>number</code> | The minute interval of the time picker. This controls the granularity of the minute selector (e.g., 15 for 0, 15, 30, 45). The value must be evenly divisible into 60. Only available on iOS when using time or datetime modes. On Android, this parameter is ignored. | <code>1</code> | 6.1.0 |

</docgen-api>

Expand Down
8 changes: 4 additions & 4 deletions packages/datetime-picker/ios/Plugin/DatetimePicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import Foundation
self.config = config
}

@objc public func presentDatetimePicker(date: Date, minDate: Date?, maxDate: Date?, locale: Locale?, cancelButtonText: String, doneButtonText: String, theme: String?, completion: @escaping (Date?, ErrorCode) -> Void) {
@objc public func presentDatetimePicker(date: Date, minDate: Date?, maxDate: Date?, locale: Locale?, cancelButtonText: String, doneButtonText: String, theme: String?, minuteInterval: Int, completion: @escaping (Date?, ErrorCode) -> Void) {
closeKeyboard()
DispatchQueue.main.asyncAfter(deadline: .now() + waitForKeyboardCloseSeconds) {
RPicker.selectDate(title: "", cancelText: cancelButtonText, doneText: doneButtonText, datePickerMode: .dateAndTime, selectedDate: date,
minDate: minDate, maxDate: maxDate, locale: locale, theme: self.getTheme(unconvertedTheme: theme), completion: { (date, errorCode) in
minDate: minDate, maxDate: maxDate, locale: locale, theme: self.getTheme(unconvertedTheme: theme), minuteInterval: minuteInterval, completion: { (date, errorCode) in
completion(date, errorCode)
})
}
Expand All @@ -32,12 +32,12 @@ import Foundation
}
}

@objc public func presentTimePicker(date: Date, locale: Locale?, cancelButtonText: String, doneButtonText: String, theme: String?, completion: @escaping (Date?, ErrorCode) -> Void) {
@objc public func presentTimePicker(date: Date, locale: Locale?, cancelButtonText: String, doneButtonText: String, theme: String?, minuteInterval: Int, completion: @escaping (Date?, ErrorCode) -> Void) {
closeKeyboard()
DispatchQueue.main.asyncAfter(deadline: .now() + waitForKeyboardCloseSeconds) {
RPicker.selectDate(title: "", cancelText: cancelButtonText, doneText: doneButtonText,
datePickerMode: .time, selectedDate: date, locale: locale, style: DatetimePickerStyle.wheel,
theme: self.getTheme(unconvertedTheme: theme), completion: { (date, errorCode) in
theme: self.getTheme(unconvertedTheme: theme), minuteInterval: minuteInterval, completion: { (date, errorCode) in
completion(date, errorCode)
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class DatetimePickerPlugin: CAPPlugin, CAPBridgedPlugin {
let value = call.getString("value")
let cancelButtonText = call.getString("cancelButtonText", "Cancel")
let doneButtonText = call.getString("doneButtonText", "Ok")
let minuteInterval = call.getInt("minuteInterval", 1)

var locale: Locale?
if let localeString = localeString {
Expand Down Expand Up @@ -74,13 +75,13 @@ public class DatetimePickerPlugin: CAPPlugin, CAPBridgedPlugin {

if mode == "datetime" {
implementation?.presentDatetimePicker(date: date, minDate: minDate, maxDate: maxDate, locale: locale,
cancelButtonText: cancelButtonText, doneButtonText: doneButtonText, theme: theme, completion: completion)
cancelButtonText: cancelButtonText, doneButtonText: doneButtonText, theme: theme, minuteInterval: minuteInterval, completion: completion)
} else if mode == "date" {
implementation?.presentDatePicker(date: date, minDate: minDate, maxDate: maxDate, locale: locale,
cancelButtonText: cancelButtonText, doneButtonText: doneButtonText, theme: theme, completion: completion)
} else if mode == "time" {
implementation?.presentTimePicker(date: date, locale: locale, cancelButtonText: cancelButtonText,
doneButtonText: doneButtonText, theme: theme, completion: completion)
doneButtonText: doneButtonText, theme: theme, minuteInterval: minuteInterval, completion: completion)
} else {
call.reject(errorModeInvalid)
}
Expand Down
14 changes: 10 additions & 4 deletions packages/datetime-picker/ios/Plugin/RPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ import UIKit
locale: Locale? = nil,
style: DatetimePickerStyle = .inline,
theme: Theme = .auto,
minuteInterval: Int = 1,
completion: ((_ date: Date?, _ errorCode: ErrorCode) -> Void)?) {

guard let vc = controller(title: title, cancelText: cancelText, doneText: doneText, datePickerMode: datePickerMode,
selectedDate: selectedDate, minDate: minDate, maxDate: maxDate, locale: locale, style: style, theme: theme) else { return }
selectedDate: selectedDate, minDate: minDate, maxDate: maxDate, locale: locale, style: style, theme: theme, minuteInterval: minuteInterval) else { return }

vc.onDateSelected = { (selectedData) in
completion?(selectedData, ErrorCode.none)
Expand All @@ -70,14 +71,15 @@ import UIKit
maxDate: Date? = nil,
locale: Locale? = nil,
style: DatetimePickerStyle = .inline,
theme: Theme = .auto) -> RPickerController? {
theme: Theme = .auto,
minuteInterval: Int = 1) -> RPickerController? {

if let cc = UIWindow.currentController {
if RPicker.sharedInstance.isPresented == false {
RPicker.sharedInstance.isPresented = true

let vc = RPickerController(title: title, cancelText: cancelText, doneText: doneText, datePickerMode: datePickerMode,
selectedDate: selectedDate, minDate: minDate, maxDate: maxDate, locale: locale, style: style, theme: theme)
selectedDate: selectedDate, minDate: minDate, maxDate: maxDate, locale: locale, style: style, theme: theme, minuteInterval: minuteInterval)

vc.modalPresentationStyle = .overCurrentContext
vc.modalTransitionStyle = .crossDissolve
Expand Down Expand Up @@ -133,6 +135,7 @@ class RPickerController: UIViewController {
var datePickerMode: UIDatePicker.Mode = .date
var datePickerStyle: DatetimePickerStyle = .inline
var theme: Theme = .auto
var minuteInterval: Int = 1

// MARK: - Private variables
private let barViewHeight: CGFloat = 44
Expand All @@ -152,7 +155,8 @@ class RPickerController: UIViewController {
maxDate: Date? = nil,
locale: Locale? = nil,
style: DatetimePickerStyle = .inline,
theme: Theme = .auto) {
theme: Theme = .auto,
minuteInterval: Int = 1) {

self.titleText = title
self.cancelText = cancelText
Expand All @@ -164,6 +168,7 @@ class RPickerController: UIViewController {
self.locale = locale
self.datePickerStyle = style
self.theme = theme
self.minuteInterval = minuteInterval

super.init(nibName: nil, bundle: nil)

Expand Down Expand Up @@ -312,6 +317,7 @@ class RPickerController: UIViewController {
picker.maximumDate = maxDate
picker.date = selectedDate
picker.datePickerMode = datePickerMode
picker.minuteInterval = minuteInterval
if let locale = locale {
picker.locale = locale
}
Expand Down
12 changes: 12 additions & 0 deletions packages/datetime-picker/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ export interface PresentOptions {
* @since 5.1.0
*/
androidDatePickerMode?: 'calendar' | 'spinner';
/**
* The minute interval of the time picker.
* This controls the granularity of the minute selector (e.g., 15 for 0, 15, 30, 45).
* The value must be evenly divisible into 60.
*
* Only available on iOS when using time or datetime modes.
* On Android, this parameter is ignored.
*
* @since 7.1.0
* @default 1
*/
minuteInterval?: number;
}

export interface PresentResult {
Expand Down