react-native-platform-components 0.8.6 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -29
- package/android/src/main/java/com/platformcomponents/PCDatePickerViewManager.kt +3 -1
- package/android/src/main/java/com/platformcomponents/PCSelectionMenuView.kt +32 -8
- package/ios/PCDatePicker.mm +2 -1
- package/ios/PCDatePickerView.swift +60 -6
- package/ios/PCSelectionMenu.mm +8 -4
- package/ios/PCSelectionMenu.swift +86 -115
- package/lib/commonjs/DatePicker.js +1 -1
- package/lib/commonjs/DatePicker.js.map +1 -1
- package/lib/commonjs/DatePickerNativeComponent.ts +1 -0
- package/lib/commonjs/SelectionMenu.js +6 -1
- package/lib/commonjs/SelectionMenu.js.map +1 -1
- package/lib/module/DatePicker.js +1 -1
- package/lib/module/DatePicker.js.map +1 -1
- package/lib/module/DatePickerNativeComponent.ts +1 -0
- package/lib/module/SelectionMenu.js +6 -1
- package/lib/module/SelectionMenu.js.map +1 -1
- package/lib/typescript/commonjs/src/DatePicker.d.ts +1 -1
- package/lib/typescript/commonjs/src/DatePicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts +1 -0
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SelectionMenu.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePicker.d.ts +1 -1
- package/lib/typescript/module/src/DatePicker.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts +1 -0
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/SelectionMenu.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/DatePicker.tsx +2 -2
- package/src/DatePickerNativeComponent.ts +1 -0
- package/src/SelectionMenu.tsx +9 -1
package/README.md
CHANGED
|
@@ -174,9 +174,9 @@ export function Example() {
|
|
|
174
174
|
visible={visible}
|
|
175
175
|
presentation="modal"
|
|
176
176
|
mode="date"
|
|
177
|
-
onConfirm={(d) => {
|
|
177
|
+
onConfirm={(d, confirmed) => {
|
|
178
178
|
setDate(d);
|
|
179
|
-
setVisible(false);
|
|
179
|
+
if (confirmed) setVisible(false);
|
|
180
180
|
}}
|
|
181
181
|
onClosed={() => setVisible(false)}
|
|
182
182
|
ios={{ preferredStyle: 'inline' }}
|
|
@@ -200,7 +200,7 @@ export function Example() {
|
|
|
200
200
|
date={date}
|
|
201
201
|
presentation="embedded"
|
|
202
202
|
mode="date"
|
|
203
|
-
onConfirm={(d) => setDate(d)}
|
|
203
|
+
onConfirm={(d, confirmed) => setDate(d)}
|
|
204
204
|
ios={{ preferredStyle: 'inline' }}
|
|
205
205
|
android={{ material: 'system' }}
|
|
206
206
|
/>
|
|
@@ -458,18 +458,18 @@ Native date & time picker using **platform system pickers**.
|
|
|
458
458
|
|
|
459
459
|
### Props
|
|
460
460
|
|
|
461
|
-
| Prop | Type | Description
|
|
462
|
-
| -------------- | ------------------------------------------------------- |
|
|
463
|
-
| `date` | `Date \| null` | Controlled date value
|
|
464
|
-
| `minDate` | `Date \| null` | Minimum selectable date
|
|
465
|
-
| `maxDate` | `Date \| null` | Maximum selectable date
|
|
466
|
-
| `locale` | `string` | Locale identifier (e.g., `'en-US'`)
|
|
467
|
-
| `timeZoneName` | `string` | Time zone identifier
|
|
468
|
-
| `mode` | `'date' \| 'time' \| 'dateAndTime' \| 'countDownTimer'` | Picker mode
|
|
469
|
-
| `presentation` | `'modal' \| 'embedded'` | Presentation style
|
|
470
|
-
| `visible` | `boolean` | Controls modal visibility (modal mode only)
|
|
471
|
-
| `onConfirm` | `(date: Date) => void`
|
|
472
|
-
| `onClosed` | `() => void` | Called when modal is dismissed
|
|
461
|
+
| Prop | Type | Description |
|
|
462
|
+
| -------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
463
|
+
| `date` | `Date \| null` | Controlled date value |
|
|
464
|
+
| `minDate` | `Date \| null` | Minimum selectable date |
|
|
465
|
+
| `maxDate` | `Date \| null` | Maximum selectable date |
|
|
466
|
+
| `locale` | `string` | Locale identifier (e.g., `'en-US'`) |
|
|
467
|
+
| `timeZoneName` | `string` | Time zone identifier |
|
|
468
|
+
| `mode` | `'date' \| 'time' \| 'dateAndTime' \| 'countDownTimer'` | Picker mode |
|
|
469
|
+
| `presentation` | `'modal' \| 'embedded'` | Presentation style |
|
|
470
|
+
| `visible` | `boolean` | Controls modal visibility (modal mode only) |
|
|
471
|
+
| `onConfirm` | `(date: Date, confirmed: boolean) => void` | Called on date change; `confirmed` is `true` for deliberate selections (see below) |
|
|
472
|
+
| `onClosed` | `() => void` | Called when modal is dismissed |
|
|
473
473
|
|
|
474
474
|
### iOS Props (`ios`)
|
|
475
475
|
|
|
@@ -490,6 +490,33 @@ Native date & time picker using **platform system pickers**.
|
|
|
490
490
|
| `positiveButtonTitle` | `string` | Custom confirm button text |
|
|
491
491
|
| `negativeButtonTitle` | `string` | Custom cancel button text |
|
|
492
492
|
|
|
493
|
+
### The `confirmed` Flag
|
|
494
|
+
|
|
495
|
+
`onConfirm` fires on every date/time change, but the second argument (`confirmed`) lets you distinguish between browsing and deliberate selections:
|
|
496
|
+
|
|
497
|
+
| Platform / Mode | Every change | Deliberate selection |
|
|
498
|
+
| -------------------- | ---------------------------------------- | ------------------------------------------------------ |
|
|
499
|
+
| **iOS modal** | `confirmed: false` (scrolling the wheel) | `confirmed: true` (tapping the already-selected value) |
|
|
500
|
+
| **iOS embedded** | `confirmed: true` | — |
|
|
501
|
+
| **Android modal** | — | `confirmed: true` (pressing OK) |
|
|
502
|
+
| **Android embedded** | `confirmed: true` | — |
|
|
503
|
+
|
|
504
|
+
A common pattern is to close the modal only on a confirmed selection:
|
|
505
|
+
|
|
506
|
+
```tsx
|
|
507
|
+
<DatePicker
|
|
508
|
+
date={date}
|
|
509
|
+
visible={visible}
|
|
510
|
+
presentation="modal"
|
|
511
|
+
mode="time"
|
|
512
|
+
onConfirm={(d, confirmed) => {
|
|
513
|
+
setDate(d);
|
|
514
|
+
if (confirmed) setVisible(false);
|
|
515
|
+
}}
|
|
516
|
+
onClosed={() => setVisible(false)}
|
|
517
|
+
/>
|
|
518
|
+
```
|
|
519
|
+
|
|
493
520
|
---
|
|
494
521
|
|
|
495
522
|
## ContextMenu
|
|
@@ -635,12 +662,12 @@ Native glass morphism effect using **UIGlassEffect** on iOS 26+. On Android and
|
|
|
635
662
|
|
|
636
663
|
### iOS Props (`ios`)
|
|
637
664
|
|
|
638
|
-
| Prop
|
|
639
|
-
|
|
|
640
|
-
| `effect`
|
|
641
|
-
| `interactive`
|
|
642
|
-
| `tintColor`
|
|
643
|
-
| `colorScheme`
|
|
665
|
+
| Prop | Type | Description |
|
|
666
|
+
| ------------- | -------------------------------- | ---------------------------------------------------- |
|
|
667
|
+
| `effect` | `'clear' \| 'regular' \| 'none'` | Glass effect intensity (default: `'regular'`) |
|
|
668
|
+
| `interactive` | `boolean` | Enable touch interaction feedback (default: `false`) |
|
|
669
|
+
| `tintColor` | `string` | Overlay tint color (hex string) |
|
|
670
|
+
| `colorScheme` | `'light' \| 'dark' \| 'system'` | Appearance mode (default: `'system'`) |
|
|
644
671
|
|
|
645
672
|
### Android Props (`android`)
|
|
646
673
|
|
|
@@ -704,14 +731,14 @@ This is intentional. The goal is native fidelity, not pixel-level customization.
|
|
|
704
731
|
|
|
705
732
|
All color props in this library support the same formats as React Native's `backgroundColor`:
|
|
706
733
|
|
|
707
|
-
| Format | Example
|
|
708
|
-
|
|
|
709
|
-
| Hex
|
|
710
|
-
| RGB
|
|
711
|
-
| RGBA
|
|
712
|
-
| HSL
|
|
713
|
-
| HSLA
|
|
714
|
-
| Named
|
|
734
|
+
| Format | Example | Description |
|
|
735
|
+
| ------ | --------------------------------- | ---------------------------------- |
|
|
736
|
+
| Hex | `#RGB`, `#RRGGBB`, `#RRGGBBAA` | Standard hex colors |
|
|
737
|
+
| RGB | `rgb(255, 0, 0)` | RGB values (0-255) |
|
|
738
|
+
| RGBA | `rgba(255, 0, 0, 0.5)` | RGB with alpha (0-1) |
|
|
739
|
+
| HSL | `hsl(0, 100%, 50%)` | Hue (0-360), saturation, lightness |
|
|
740
|
+
| HSLA | `hsla(0, 100%, 50%, 0.5)` | HSL with alpha (0-1) |
|
|
741
|
+
| Named | `red`, `steelblue`, `transparent` | CSS named colors |
|
|
715
742
|
|
|
716
743
|
**Props that accept colors:**
|
|
717
744
|
|
|
@@ -141,12 +141,14 @@ class PCDatePickerViewManager :
|
|
|
141
141
|
|
|
142
142
|
private class ConfirmEvent(
|
|
143
143
|
surfaceId: Int,
|
|
144
|
-
private val ts: Double
|
|
144
|
+
private val ts: Double,
|
|
145
|
+
private val confirmed: Boolean = true
|
|
145
146
|
) : Event<ConfirmEvent>(surfaceId) {
|
|
146
147
|
override fun getEventName(): String = "topConfirm"
|
|
147
148
|
override fun dispatch(rctEventEmitter: RCTEventEmitter) {
|
|
148
149
|
val payload = com.facebook.react.bridge.Arguments.createMap().apply {
|
|
149
150
|
putDouble("timestampMs", ts)
|
|
151
|
+
putBoolean("confirmed", confirmed)
|
|
150
152
|
}
|
|
151
153
|
rctEventEmitter.receiveEvent(viewTag, eventName, payload)
|
|
152
154
|
}
|
|
@@ -178,16 +178,23 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
178
178
|
val inlineWidget: View? = inlineLayout ?: inlineSpinner
|
|
179
179
|
if (inlineWidget == null) return
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
val density = resources.displayMetrics.density
|
|
182
|
+
|
|
183
|
+
// Use AT_MOST with a large upper bound rather than UNSPECIFIED.
|
|
184
|
+
// TextInputLayout (and other composite views) can return incorrect
|
|
185
|
+
// intrinsic widths with UNSPECIFIED because their children don't
|
|
186
|
+
// handle that mode reliably. AT_MOST mirrors normal layout behavior.
|
|
187
|
+
val maxPx = (10000 * density).toInt()
|
|
188
|
+
val widthSpec = MeasureSpec.makeMeasureSpec(maxPx, MeasureSpec.AT_MOST)
|
|
183
189
|
val heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
|
|
184
190
|
inlineWidget.measure(widthSpec, heightSpec)
|
|
191
|
+
val intrinsicWidthPx = inlineWidget.measuredWidth
|
|
192
|
+
val intrinsicHeightPx = inlineWidget.measuredHeight
|
|
185
193
|
|
|
186
|
-
val widthDp = PixelUtil.toDIPFromPixel(
|
|
187
|
-
val
|
|
188
|
-
val rawHeightDp = PixelUtil.toDIPFromPixel(rawHeightPx.toFloat())
|
|
194
|
+
val widthDp = PixelUtil.toDIPFromPixel(intrinsicWidthPx.toFloat())
|
|
195
|
+
val rawHeightDp = PixelUtil.toDIPFromPixel(intrinsicHeightPx.toFloat())
|
|
189
196
|
|
|
190
|
-
Log.d(TAG, "updateFrameSizeState: widget=${inlineWidget.javaClass.simpleName},
|
|
197
|
+
Log.d(TAG, "updateFrameSizeState: widget=${inlineWidget.javaClass.simpleName}, intrinsicWidthPx=$intrinsicWidthPx, widthDp=$widthDp, intrinsicHeightPx=$intrinsicHeightPx, rawHeightDp=$rawHeightDp, minimumHeight=$minimumHeight, density=$density")
|
|
191
198
|
|
|
192
199
|
// Only update if changed
|
|
193
200
|
if (widthDp != lastReportedWidth || rawHeightDp != lastReportedHeight) {
|
|
@@ -242,6 +249,11 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
242
249
|
placeholder = value
|
|
243
250
|
inlineLayout?.hint = placeholder
|
|
244
251
|
// Spinner doesn't support placeholder
|
|
252
|
+
|
|
253
|
+
// Re-measure after placeholder change
|
|
254
|
+
if (anchorMode == "inline") {
|
|
255
|
+
post { updateFrameSizeState() }
|
|
256
|
+
}
|
|
245
257
|
}
|
|
246
258
|
|
|
247
259
|
fun applyAnchorMode(value: String?) {
|
|
@@ -311,6 +323,8 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
311
323
|
headlessDismissProgrammatic = false
|
|
312
324
|
headlessDismissAfterSelect = false
|
|
313
325
|
hasRequestedLayoutUpdate = false
|
|
326
|
+
lastReportedWidth = 0f
|
|
327
|
+
lastReportedHeight = 0f
|
|
314
328
|
|
|
315
329
|
// Headless should be invisible but anchorable.
|
|
316
330
|
alpha = if (anchorMode == "headless") 0.01f else 1f
|
|
@@ -344,7 +358,7 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
344
358
|
// Must set box background mode BEFORE setting endIconMode to avoid IllegalStateException
|
|
345
359
|
val til = TextInputLayout(context).apply {
|
|
346
360
|
layoutParams = FrameLayout.LayoutParams(
|
|
347
|
-
FrameLayout.LayoutParams.
|
|
361
|
+
FrameLayout.LayoutParams.WRAP_CONTENT,
|
|
348
362
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
|
349
363
|
)
|
|
350
364
|
// Set box background mode first - required for END_ICON_DROPDOWN_MENU
|
|
@@ -463,7 +477,7 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
463
477
|
|
|
464
478
|
sp.apply {
|
|
465
479
|
layoutParams = FrameLayout.LayoutParams(
|
|
466
|
-
FrameLayout.LayoutParams.
|
|
480
|
+
FrameLayout.LayoutParams.WRAP_CONTENT,
|
|
467
481
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
|
468
482
|
)
|
|
469
483
|
visibility = View.VISIBLE
|
|
@@ -529,6 +543,11 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
529
543
|
}
|
|
530
544
|
|
|
531
545
|
refreshHeadlessMenu()
|
|
546
|
+
|
|
547
|
+
// Re-measure after adapter change so Fabric state reflects new content width
|
|
548
|
+
if (anchorMode == "inline") {
|
|
549
|
+
post { updateFrameSizeState() }
|
|
550
|
+
}
|
|
532
551
|
}
|
|
533
552
|
|
|
534
553
|
private fun refreshSelections() {
|
|
@@ -555,6 +574,11 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
555
574
|
|
|
556
575
|
// Update headless menu checked state
|
|
557
576
|
refreshHeadlessMenu()
|
|
577
|
+
|
|
578
|
+
// Re-measure after selection change so Fabric state reflects new text width
|
|
579
|
+
if (anchorMode == "inline") {
|
|
580
|
+
post { updateFrameSizeState() }
|
|
581
|
+
}
|
|
558
582
|
}
|
|
559
583
|
|
|
560
584
|
// ---- Inline dropdown overlay ----
|
package/ios/PCDatePicker.mm
CHANGED
|
@@ -46,13 +46,14 @@ using namespace facebook::react;
|
|
|
46
46
|
|
|
47
47
|
__weak __typeof(self) weakSelf = self;
|
|
48
48
|
|
|
49
|
-
_datePickerView.onChangeHandler = ^(NSNumber *ms) {
|
|
49
|
+
_datePickerView.onChangeHandler = ^(NSNumber *ms, BOOL confirmed) {
|
|
50
50
|
__typeof(self) strongSelf = weakSelf;
|
|
51
51
|
if (!strongSelf)
|
|
52
52
|
return;
|
|
53
53
|
|
|
54
54
|
PCDatePickerEventEmitter::OnConfirm event{};
|
|
55
55
|
event.timestampMs = ms.doubleValue;
|
|
56
|
+
event.confirmed = confirmed;
|
|
56
57
|
|
|
57
58
|
strongSelf.eventEmitterTyped.onConfirm(event);
|
|
58
59
|
};
|
|
@@ -6,25 +6,28 @@ private let logger = Logger(subsystem: "com.platformcomponents", category: "Date
|
|
|
6
6
|
@objcMembers
|
|
7
7
|
public final class PCDatePickerView: UIControl,
|
|
8
8
|
UIPopoverPresentationControllerDelegate,
|
|
9
|
-
UIAdaptivePresentationControllerDelegate
|
|
9
|
+
UIAdaptivePresentationControllerDelegate,
|
|
10
|
+
UIGestureRecognizerDelegate
|
|
10
11
|
{
|
|
11
12
|
// MARK: - UI
|
|
12
13
|
private let picker = UIDatePicker()
|
|
13
14
|
private var modalVC: UIViewController?
|
|
14
15
|
private var inlineConstraints: [NSLayoutConstraint] = []
|
|
16
|
+
private var confirmWorkItem: DispatchWorkItem?
|
|
17
|
+
private var tapGesture: UITapGestureRecognizer?
|
|
15
18
|
|
|
16
|
-
// Suppress
|
|
19
|
+
// Suppress "programmatic" valueChanged events (apply props / initial present settle).
|
|
17
20
|
private var suppressChangeEvents = false
|
|
18
21
|
private func suppressNextChangesBriefly() {
|
|
19
22
|
suppressChangeEvents = true
|
|
20
|
-
// Clear on next runloop tick (usually enough to skip the
|
|
23
|
+
// Clear on next runloop tick (usually enough to skip the "settle" event).
|
|
21
24
|
DispatchQueue.main.async { [weak self] in
|
|
22
25
|
self?.suppressChangeEvents = false
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
// MARK: - Events (wired from ObjC++)
|
|
27
|
-
public var onChangeHandler: ((NSNumber) -> Void)?
|
|
30
|
+
public var onChangeHandler: ((NSNumber, Bool) -> Void)?
|
|
28
31
|
public var onCancelHandler: (() -> Void)?
|
|
29
32
|
|
|
30
33
|
// MARK: - Props
|
|
@@ -283,6 +286,14 @@ public final class PCDatePickerView: UIControl,
|
|
|
283
286
|
// Prevent "settle" events right as we present.
|
|
284
287
|
suppressNextChangesBriefly()
|
|
285
288
|
|
|
289
|
+
// Set up tap-to-confirm gesture for modal mode
|
|
290
|
+
confirmWorkItem?.cancel()
|
|
291
|
+
let tap = UITapGestureRecognizer(target: self, action: #selector(handlePickerTap))
|
|
292
|
+
tap.cancelsTouchesInView = false
|
|
293
|
+
tap.delegate = self
|
|
294
|
+
picker.addGestureRecognizer(tap)
|
|
295
|
+
tapGesture = tap
|
|
296
|
+
|
|
286
297
|
let vc = UIViewController()
|
|
287
298
|
picker.translatesAutoresizingMaskIntoConstraints = false
|
|
288
299
|
vc.view.addSubview(picker)
|
|
@@ -343,6 +354,11 @@ public final class PCDatePickerView: UIControl,
|
|
|
343
354
|
guard let vc = modalVC else { return }
|
|
344
355
|
logger.debug("dismissIfNeeded: dismissing modal, emitCancel=\(emitCancel)")
|
|
345
356
|
modalVC = nil
|
|
357
|
+
confirmWorkItem?.cancel()
|
|
358
|
+
if let tap = tapGesture {
|
|
359
|
+
picker.removeGestureRecognizer(tap)
|
|
360
|
+
tapGesture = nil
|
|
361
|
+
}
|
|
346
362
|
vc.dismiss(animated: true) { [weak self] in
|
|
347
363
|
guard let self else { return }
|
|
348
364
|
if emitCancel { self.onCancelHandler?() }
|
|
@@ -360,6 +376,11 @@ public final class PCDatePickerView: UIControl,
|
|
|
360
376
|
public func presentationControllerDidDismiss(_ presentationController: UIPresentationController)
|
|
361
377
|
{
|
|
362
378
|
modalVC = nil
|
|
379
|
+
confirmWorkItem?.cancel()
|
|
380
|
+
if let tap = tapGesture {
|
|
381
|
+
picker.removeGestureRecognizer(tap)
|
|
382
|
+
tapGesture = nil
|
|
383
|
+
}
|
|
363
384
|
onCancelHandler?()
|
|
364
385
|
}
|
|
365
386
|
|
|
@@ -367,17 +388,50 @@ public final class PCDatePickerView: UIControl,
|
|
|
367
388
|
_ popoverPresentationController: UIPopoverPresentationController
|
|
368
389
|
) {
|
|
369
390
|
modalVC = nil
|
|
391
|
+
confirmWorkItem?.cancel()
|
|
392
|
+
if let tap = tapGesture {
|
|
393
|
+
picker.removeGestureRecognizer(tap)
|
|
394
|
+
tapGesture = nil
|
|
395
|
+
}
|
|
370
396
|
onCancelHandler?()
|
|
371
397
|
}
|
|
372
398
|
|
|
399
|
+
// MARK: - Gesture delegate
|
|
400
|
+
|
|
401
|
+
public func gestureRecognizer(
|
|
402
|
+
_ gestureRecognizer: UIGestureRecognizer,
|
|
403
|
+
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
|
|
404
|
+
) -> Bool {
|
|
405
|
+
return gestureRecognizer === tapGesture
|
|
406
|
+
}
|
|
407
|
+
|
|
373
408
|
// MARK: - Value changes
|
|
374
409
|
|
|
375
410
|
@objc private func handleValueChanged() {
|
|
376
|
-
// Skip
|
|
411
|
+
// Skip "programmatic/settle" changes
|
|
377
412
|
if suppressChangeEvents { return }
|
|
378
413
|
|
|
379
414
|
let ms = picker.date.timeIntervalSince1970 * 1000.0
|
|
380
|
-
|
|
415
|
+
let isModal = presentation == "modal" && modalVC != nil
|
|
416
|
+
onChangeHandler?(NSNumber(value: ms), !isModal)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
@objc private func handlePickerTap() {
|
|
420
|
+
guard presentation == "modal", modalVC != nil else { return }
|
|
421
|
+
|
|
422
|
+
confirmWorkItem?.cancel()
|
|
423
|
+
|
|
424
|
+
let dateAtTap = picker.date
|
|
425
|
+
let workItem = DispatchWorkItem { [weak self] in
|
|
426
|
+
guard let self, self.modalVC != nil else { return }
|
|
427
|
+
// If picker date is still the same, the tap was on the selected row → confirm
|
|
428
|
+
if self.picker.date == dateAtTap {
|
|
429
|
+
let ms = dateAtTap.timeIntervalSince1970 * 1000.0
|
|
430
|
+
self.onChangeHandler?(NSNumber(value: ms), true)
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
confirmWorkItem = workItem
|
|
434
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.15, execute: workItem)
|
|
381
435
|
}
|
|
382
436
|
|
|
383
437
|
// MARK: - Apply props (avoid firing valueChanged)
|
package/ios/PCSelectionMenu.mm
CHANGED
|
@@ -63,6 +63,11 @@ static inline bool OptionsEqual(
|
|
|
63
63
|
__typeof(self) strongSelf = weakSelf;
|
|
64
64
|
if (!strongSelf) return;
|
|
65
65
|
|
|
66
|
+
// The Swift view has already updated its content (selectedData + sync()).
|
|
67
|
+
// Trigger measurement now so Yoga gets the new size before the React
|
|
68
|
+
// round-trip, preventing a frame of clipped text.
|
|
69
|
+
[strongSelf updateMeasurements];
|
|
70
|
+
|
|
66
71
|
auto eventEmitter =
|
|
67
72
|
std::static_pointer_cast<const PCSelectionMenuEventEmitter>(
|
|
68
73
|
strongSelf->_eventEmitter);
|
|
@@ -201,10 +206,9 @@ static inline bool OptionsEqual(
|
|
|
201
206
|
if (_state == nullptr)
|
|
202
207
|
return;
|
|
203
208
|
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
CGSize size = [_view sizeForLayoutWithConstrainedTo:CGSizeMake(w, 0)];
|
|
209
|
+
// Measure unconstrained so the view reports its true intrinsic size.
|
|
210
|
+
// Yoga's measureContent() will clamp to parent layout constraints.
|
|
211
|
+
CGSize size = [_view sizeForLayoutWithConstrainedTo:CGSizeMake(CGFLOAT_MAX, 0)];
|
|
208
212
|
|
|
209
213
|
PCSelectionMenuStateFrameSize next;
|
|
210
214
|
next.frameSize = {(Float)size.width, (Float)size.height};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import os.log
|
|
2
|
-
import SwiftUI
|
|
3
2
|
import UIKit
|
|
4
3
|
|
|
5
4
|
private let logger = Logger(subsystem: "com.platformcomponents", category: "SelectionMenu")
|
|
@@ -11,54 +10,6 @@ struct PCSelectionMenuOption {
|
|
|
11
10
|
let data: String
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
final class PCSelectionMenuModel: ObservableObject {
|
|
15
|
-
@Published var options: [PCSelectionMenuOption] = []
|
|
16
|
-
@Published var selectedData: String = "" // sentinel = no selection
|
|
17
|
-
@Published var placeholder: String = "Select"
|
|
18
|
-
@Published var interactivity: String = "enabled" // "enabled" | "disabled"
|
|
19
|
-
|
|
20
|
-
var isDisabled: Bool { interactivity == "disabled" }
|
|
21
|
-
|
|
22
|
-
var displayTitle: String {
|
|
23
|
-
if let opt = options.first(where: { $0.data == selectedData }), !selectedData.isEmpty {
|
|
24
|
-
return opt.label
|
|
25
|
-
}
|
|
26
|
-
return placeholder
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
var hasOptions: Bool { !options.isEmpty }
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
private struct PCSelectionMenuInlinePickerView: View {
|
|
33
|
-
@ObservedObject var model: PCSelectionMenuModel
|
|
34
|
-
let onSelectIndex: (Int) -> Void
|
|
35
|
-
|
|
36
|
-
var body: some View {
|
|
37
|
-
Menu {
|
|
38
|
-
ForEach(Array(model.options.enumerated()), id: \.offset) { i, opt in
|
|
39
|
-
Button(opt.label) { onSelectIndex(i) }
|
|
40
|
-
}
|
|
41
|
-
} label: {
|
|
42
|
-
HStack(spacing: 8) {
|
|
43
|
-
Text(model.displayTitle)
|
|
44
|
-
.font(.body)
|
|
45
|
-
.lineLimit(1)
|
|
46
|
-
.truncationMode(.tail)
|
|
47
|
-
|
|
48
|
-
Spacer(minLength: 0)
|
|
49
|
-
|
|
50
|
-
Image(systemName: "chevron.up.chevron.down")
|
|
51
|
-
.imageScale(.small)
|
|
52
|
-
.opacity(0.7)
|
|
53
|
-
}
|
|
54
|
-
.frame(maxWidth: .infinity, alignment: .leading)
|
|
55
|
-
.contentShape(Rectangle())
|
|
56
|
-
.padding(.vertical, 10)
|
|
57
|
-
}
|
|
58
|
-
.disabled(model.isDisabled || !model.hasOptions)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
13
|
@objcMembers
|
|
63
14
|
public final class PCSelectionMenuView: UIControl {
|
|
64
15
|
// MARK: - Props (set from ObjC++)
|
|
@@ -93,10 +44,12 @@ public final class PCSelectionMenuView: UIControl {
|
|
|
93
44
|
public var onSelect: ((Int, String, String) -> Void)? // (index,label,data)
|
|
94
45
|
public var onRequestClose: (() -> Void)?
|
|
95
46
|
|
|
96
|
-
// MARK: - Internal
|
|
47
|
+
// MARK: - Internal (inline UIKit views)
|
|
48
|
+
|
|
49
|
+
private var menuButton: UIButton?
|
|
50
|
+
|
|
51
|
+
// MARK: - Internal (headless)
|
|
97
52
|
|
|
98
|
-
private let model = PCSelectionMenuModel()
|
|
99
|
-
private var hostingController: UIHostingController<AnyView>?
|
|
100
53
|
private var headlessMenuView: UIView?
|
|
101
54
|
private var headlessMenuVC: UIViewController?
|
|
102
55
|
private var headlessPresentationToken: Int = 0
|
|
@@ -110,6 +63,14 @@ public final class PCSelectionMenuView: UIControl {
|
|
|
110
63
|
}
|
|
111
64
|
}
|
|
112
65
|
|
|
66
|
+
private var displayTitle: String {
|
|
67
|
+
let opts = parsedOptions
|
|
68
|
+
if !selectedData.isEmpty, let opt = opts.first(where: { $0.data == selectedData }) {
|
|
69
|
+
return opt.label
|
|
70
|
+
}
|
|
71
|
+
return placeholder ?? "Select"
|
|
72
|
+
}
|
|
73
|
+
|
|
113
74
|
// MARK: - Init
|
|
114
75
|
|
|
115
76
|
public override init(frame: CGRect) {
|
|
@@ -155,45 +116,75 @@ public final class PCSelectionMenuView: UIControl {
|
|
|
155
116
|
}
|
|
156
117
|
|
|
157
118
|
private func sync() {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
model.placeholder = placeholder ?? "Select"
|
|
161
|
-
model.interactivity = interactivity
|
|
119
|
+
// Update the button title
|
|
120
|
+
menuButton?.setTitle(displayTitle, for: .normal)
|
|
162
121
|
|
|
163
|
-
|
|
122
|
+
// Rebuild the UIMenu with current options
|
|
123
|
+
if anchorMode == "inline" {
|
|
124
|
+
rebuildMenu()
|
|
125
|
+
}
|
|
164
126
|
|
|
165
127
|
invalidateIntrinsicContentSize()
|
|
166
128
|
setNeedsLayout()
|
|
167
129
|
}
|
|
168
130
|
|
|
169
|
-
|
|
170
|
-
return AnyView(PCSelectionMenuInlinePickerView(
|
|
171
|
-
model: model,
|
|
172
|
-
onSelectIndex: { [weak self] idx in
|
|
173
|
-
guard let self else { return }
|
|
174
|
-
let opts = self.parsedOptions
|
|
175
|
-
guard idx >= 0, idx < opts.count else { return }
|
|
176
|
-
let opt = opts[idx]
|
|
177
|
-
self.selectedData = opt.data
|
|
178
|
-
self.onSelect?(idx, opt.label, opt.data)
|
|
179
|
-
}
|
|
180
|
-
))
|
|
181
|
-
}
|
|
131
|
+
// MARK: - Inline (UIKit-based)
|
|
182
132
|
|
|
183
133
|
private func installInlineIfNeeded() {
|
|
184
|
-
guard
|
|
185
|
-
|
|
134
|
+
guard menuButton == nil else { return }
|
|
135
|
+
|
|
136
|
+
var config = UIButton.Configuration.plain()
|
|
137
|
+
config.baseForegroundColor = .tintColor
|
|
138
|
+
config.image = UIImage(systemName: "chevron.up.chevron.down")
|
|
139
|
+
config.preferredSymbolConfigurationForImage = UIImage.SymbolConfiguration(scale: .small)
|
|
140
|
+
config.imagePlacement = .trailing
|
|
141
|
+
config.imagePadding = 8
|
|
142
|
+
config.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0)
|
|
143
|
+
|
|
144
|
+
let button = UIButton(configuration: config)
|
|
145
|
+
button.showsMenuAsPrimaryAction = true
|
|
146
|
+
button.changesSelectionAsPrimaryAction = false
|
|
147
|
+
|
|
148
|
+
addSubview(button)
|
|
149
|
+
menuButton = button
|
|
150
|
+
|
|
151
|
+
rebuildMenu()
|
|
152
|
+
setNeedsLayout()
|
|
186
153
|
}
|
|
187
154
|
|
|
188
155
|
private func uninstallInlineIfNeeded() {
|
|
189
|
-
guard let
|
|
190
|
-
|
|
156
|
+
guard let button = menuButton else { return }
|
|
157
|
+
button.removeFromSuperview()
|
|
158
|
+
menuButton = nil
|
|
159
|
+
}
|
|
191
160
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
161
|
+
private func rebuildMenu() {
|
|
162
|
+
let opts = parsedOptions
|
|
163
|
+
let disabled = (interactivity == "disabled") || opts.isEmpty
|
|
164
|
+
let actions = opts.enumerated().map { (idx, opt) in
|
|
165
|
+
UIAction(title: opt.label) { [weak self] _ in
|
|
166
|
+
guard let self else { return }
|
|
167
|
+
self.selectedData = opt.data
|
|
168
|
+
self.onSelect?(idx, opt.label, opt.data)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
menuButton?.menu = disabled ? nil : UIMenu(children: actions)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
override public func layoutSubviews() {
|
|
175
|
+
super.layoutSubviews()
|
|
176
|
+
guard let button = menuButton else { return }
|
|
177
|
+
let fitted = button.intrinsicContentSize
|
|
178
|
+
button.frame = CGRect(
|
|
179
|
+
x: 0,
|
|
180
|
+
y: (bounds.height - fitted.height) / 2,
|
|
181
|
+
width: fitted.width,
|
|
182
|
+
height: fitted.height
|
|
183
|
+
)
|
|
195
184
|
}
|
|
196
185
|
|
|
186
|
+
// MARK: - Headless
|
|
187
|
+
|
|
197
188
|
private func installHeadlessIfNeeded() {
|
|
198
189
|
guard headlessMenuView == nil else { return }
|
|
199
190
|
|
|
@@ -220,27 +211,6 @@ public final class PCSelectionMenuView: UIControl {
|
|
|
220
211
|
view.removeFromSuperview()
|
|
221
212
|
}
|
|
222
213
|
|
|
223
|
-
private func installHostingController() {
|
|
224
|
-
let host = UIHostingController(rootView: makeRootView())
|
|
225
|
-
host.view.translatesAutoresizingMaskIntoConstraints = false
|
|
226
|
-
host.view.backgroundColor = .clear
|
|
227
|
-
|
|
228
|
-
addSubview(host.view)
|
|
229
|
-
NSLayoutConstraint.activate([
|
|
230
|
-
host.view.topAnchor.constraint(equalTo: topAnchor),
|
|
231
|
-
host.view.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
232
|
-
host.view.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
233
|
-
host.view.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
234
|
-
])
|
|
235
|
-
|
|
236
|
-
if let parent = nearestViewController() {
|
|
237
|
-
parent.addChild(host)
|
|
238
|
-
host.didMove(toParent: parent)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
hostingController = host
|
|
242
|
-
}
|
|
243
|
-
|
|
244
214
|
private func nearestViewController() -> UIViewController? {
|
|
245
215
|
var r: UIResponder? = self
|
|
246
216
|
while let next = r?.next {
|
|
@@ -351,24 +321,26 @@ public final class PCSelectionMenuView: UIControl {
|
|
|
351
321
|
public override func sizeThatFits(_ size: CGSize) -> CGSize {
|
|
352
322
|
if anchorMode != "inline" { return CGSize(width: size.width, height: 1) }
|
|
353
323
|
|
|
354
|
-
guard let
|
|
355
|
-
return CGSize(width:
|
|
324
|
+
guard let button = menuButton else {
|
|
325
|
+
return CGSize(width: 0, height: PCConstants.minTouchTargetHeight)
|
|
356
326
|
}
|
|
357
327
|
|
|
358
|
-
let
|
|
359
|
-
|
|
360
|
-
|
|
328
|
+
let fitted = button.intrinsicContentSize
|
|
329
|
+
return CGSize(
|
|
330
|
+
width: fitted.width,
|
|
331
|
+
height: max(PCConstants.minTouchTargetHeight, fitted.height)
|
|
332
|
+
)
|
|
361
333
|
}
|
|
362
334
|
|
|
363
335
|
public override var intrinsicContentSize: CGSize {
|
|
364
336
|
if anchorMode != "inline" {
|
|
365
337
|
return CGSize(width: UIView.noIntrinsicMetric, height: 1)
|
|
366
338
|
}
|
|
367
|
-
let
|
|
368
|
-
|
|
369
|
-
|
|
339
|
+
let fitted = sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: .greatestFiniteMagnitude))
|
|
340
|
+
return CGSize(
|
|
341
|
+
width: fitted.width,
|
|
342
|
+
height: max(PCConstants.minTouchTargetHeight, fitted.height)
|
|
370
343
|
)
|
|
371
|
-
return CGSize(width: UIView.noIntrinsicMetric, height: h)
|
|
372
344
|
}
|
|
373
345
|
|
|
374
346
|
/// Called by the measuring pipeline to get the size for Yoga layout.
|
|
@@ -376,16 +348,15 @@ public final class PCSelectionMenuView: UIControl {
|
|
|
376
348
|
@objc public func sizeForLayout(withConstrainedTo constrainedSize: CGSize) -> CGSize {
|
|
377
349
|
guard anchorMode == "inline" else { return .zero }
|
|
378
350
|
|
|
379
|
-
guard let
|
|
380
|
-
return CGSize(width:
|
|
351
|
+
guard let button = menuButton else {
|
|
352
|
+
return CGSize(width: 0, height: PCConstants.minTouchTargetHeight)
|
|
381
353
|
}
|
|
382
354
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
return CGSize(width: constrainedSize.width, height: max(PCConstants.minTouchTargetHeight, fitted.height))
|
|
355
|
+
let fitted = button.intrinsicContentSize
|
|
356
|
+
return CGSize(
|
|
357
|
+
width: fitted.width,
|
|
358
|
+
height: max(PCConstants.minTouchTargetHeight, fitted.height)
|
|
359
|
+
)
|
|
389
360
|
}
|
|
390
361
|
}
|
|
391
362
|
|
|
@@ -44,7 +44,7 @@ function DatePicker(props) {
|
|
|
44
44
|
} = props;
|
|
45
45
|
const isModal = presentation === 'modal';
|
|
46
46
|
const handleConfirm = (0, _react.useCallback)(e => {
|
|
47
|
-
onConfirm?.(new Date(e.nativeEvent.timestampMs));
|
|
47
|
+
onConfirm?.(new Date(e.nativeEvent.timestampMs), e.nativeEvent.confirmed);
|
|
48
48
|
}, [onConfirm]);
|
|
49
49
|
const handleClosed = (0, _react.useCallback)(() => {
|
|
50
50
|
onClosed?.();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_DatePickerNativeComponent","_interopRequireDefault","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","NO_DATE_SENTINEL","Number","MIN_SAFE_INTEGER","dateToMsOrSentinel","d","ms","getTime","isFinite","normalizeVisible","presentation","visible","undefined","DatePicker","props","style","date","minDate","maxDate","locale","timeZoneName","mode","onConfirm","onClosed","ios","android","testID","isModal","handleConfirm","useCallback","Date","nativeEvent","timestampMs","handleClosed","nativeProps","styles","picker","dateMs","minDateMs","maxDateMs","preferredStyle","countDownDurationSeconds","minuteInterval","roundsToMinuteInterval","firstDayOfWeek","material","dialogTitle","positiveButtonTitle","negativeButtonTitle","jsx","StyleSheet","create"],"sourceRoot":"../../src","sources":["DatePicker.tsx"],"mappings":";;;;;;AACA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AAEA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,0BAAA,GAAAC,sBAAA,CAAAH,OAAA;AASqC,IAAAI,WAAA,GAAAJ,OAAA;AAAA,SAAAG,uBAAAE,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAAA,SAAAN,wBAAAM,CAAA,EAAAG,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAV,uBAAA,YAAAA,CAAAM,CAAA,EAAAG,CAAA,SAAAA,CAAA,IAAAH,CAAA,IAAAA,CAAA,CAAAC,UAAA,SAAAD,CAAA,MAAAO,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAR,OAAA,EAAAF,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAS,CAAA,MAAAF,CAAA,GAAAJ,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAE,CAAA,CAAAI,GAAA,CAAAX,CAAA,UAAAO,CAAA,CAAAK,GAAA,CAAAZ,CAAA,GAAAO,CAAA,CAAAM,GAAA,CAAAb,CAAA,EAAAS,CAAA,gBAAAN,CAAA,IAAAH,CAAA,gBAAAG,CAAA,OAAAW,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAG,CAAA,OAAAK,CAAA,IAAAD,CAAA,GAAAS,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAG,CAAA,OAAAK,CAAA,CAAAI,GAAA,IAAAJ,CAAA,CAAAK,GAAA,IAAAN,CAAA,CAAAE,CAAA,EAAAN,CAAA,EAAAK,CAAA,IAAAC,CAAA,CAAAN,CAAA,IAAAH,CAAA,CAAAG,CAAA,WAAAM,CAAA,KAAAT,CAAA,EAAAG,CAAA;AAdrC;;AA6DA;AACA;AACA,MAAMgB,gBAAgB,GAAGC,MAAM,CAACC,gBAAgB;AAEhD,SAASC,kBAAkBA,CAACC,CAA0B,EAAU;EAC9D,IAAI,CAACA,CAAC,EAAE,OAAOJ,gBAAgB;EAC/B,MAAMK,EAAE,GAAGD,CAAC,CAACE,OAAO,CAAC,CAAC;EACtB,OAAOL,MAAM,CAACM,QAAQ,CAACF,EAAE,CAAC,GAAGA,EAAE,GAAGL,gBAAgB;AACpD;AAEA,SAASQ,gBAAgBA,CACvBC,YAA+D,EAC/DC,OAA4B,EACP;EACrB;EACA,IAAID,YAAY,KAAK,OAAO,EAAE,OAAOE,SAAS;EAC9C,OAAOD,OAAO,GAAG,MAAM,GAAG,QAAQ;AACpC;AAEO,SAASE,UAAUA,CAACC,KAAsB,EAAsB;EACrE,MAAM;IACJC,KAAK;IACLC,IAAI;IACJC,OAAO;IACPC,OAAO;IACPC,MAAM;IACNC,YAAY;IACZC,IAAI;IACJX,YAAY,GAAG,OAAO;IACtBC,OAAO;IACPW,SAAS;IACTC,QAAQ;IACRC,GAAG;IACHC,OAAO;IACPC;EACF,CAAC,GAAGZ,KAAK;EAET,MAAMa,OAAO,GAAGjB,YAAY,KAAK,OAAO;EAExC,MAAMkB,aAAa,GAAG,IAAAC,kBAAW,EAC9B/C,CAAwC,IAAK;IAC5CwC,SAAS,GAAG,IAAIQ,IAAI,CAAChD,CAAC,CAACiD,WAAW,CAACC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_DatePickerNativeComponent","_interopRequireDefault","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","NO_DATE_SENTINEL","Number","MIN_SAFE_INTEGER","dateToMsOrSentinel","d","ms","getTime","isFinite","normalizeVisible","presentation","visible","undefined","DatePicker","props","style","date","minDate","maxDate","locale","timeZoneName","mode","onConfirm","onClosed","ios","android","testID","isModal","handleConfirm","useCallback","Date","nativeEvent","timestampMs","confirmed","handleClosed","nativeProps","styles","picker","dateMs","minDateMs","maxDateMs","preferredStyle","countDownDurationSeconds","minuteInterval","roundsToMinuteInterval","firstDayOfWeek","material","dialogTitle","positiveButtonTitle","negativeButtonTitle","jsx","StyleSheet","create"],"sourceRoot":"../../src","sources":["DatePicker.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.SelectionMenu = SelectionMenu;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
8
9
|
var _SelectionMenuNativeComponent = _interopRequireDefault(require("./SelectionMenuNativeComponent"));
|
|
9
10
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
11
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -55,6 +56,10 @@ function SelectionMenu(props) {
|
|
|
55
56
|
material: android.material
|
|
56
57
|
};
|
|
57
58
|
}, [android]);
|
|
59
|
+
|
|
60
|
+
// On Android, force a fresh native view when structural props change so the
|
|
61
|
+
// widget gets a clean measurement cycle (TextInputLayout caches aggressively).
|
|
62
|
+
const remountKey = _reactNative.Platform.OS === 'android' ? `${presentation}-${android?.material ?? 'system'}` : undefined;
|
|
58
63
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SelectionMenuNativeComponent.default, {
|
|
59
64
|
style: style,
|
|
60
65
|
options: options,
|
|
@@ -68,6 +73,6 @@ function SelectionMenu(props) {
|
|
|
68
73
|
ios: ios,
|
|
69
74
|
android: nativeAndroid,
|
|
70
75
|
...viewProps
|
|
71
|
-
});
|
|
76
|
+
}, remountKey);
|
|
72
77
|
}
|
|
73
78
|
//# sourceMappingURL=SelectionMenu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_SelectionMenuNativeComponent","_interopRequireDefault","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","normalizeSelectedData","selected","normalizeNativeVisible","presentation","visible","undefined","SelectionMenu","props","style","options","disabled","placeholder","onSelect","onRequestClose","ios","android","viewProps","selectedData","useMemo","nativeVisible","handleSelect","useCallback","index","label","data","nativeEvent","handleRequestClose","nativeAndroid","material","jsx","interactivity","anchorMode"],"sourceRoot":"../../src","sources":["SelectionMenu.tsx"],"mappings":";;;;;;AACA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_SelectionMenuNativeComponent","_interopRequireDefault","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","normalizeSelectedData","selected","normalizeNativeVisible","presentation","visible","undefined","SelectionMenu","props","style","options","disabled","placeholder","onSelect","onRequestClose","ios","android","viewProps","selectedData","useMemo","nativeVisible","handleSelect","useCallback","index","label","data","nativeEvent","handleRequestClose","nativeAndroid","material","remountKey","Platform","OS","jsx","interactivity","anchorMode"],"sourceRoot":"../../src","sources":["SelectionMenu.tsx"],"mappings":"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","ignoreList":[]}
|
package/lib/module/DatePicker.js
CHANGED
|
@@ -37,7 +37,7 @@ export function DatePicker(props) {
|
|
|
37
37
|
} = props;
|
|
38
38
|
const isModal = presentation === 'modal';
|
|
39
39
|
const handleConfirm = useCallback(e => {
|
|
40
|
-
onConfirm?.(new Date(e.nativeEvent.timestampMs));
|
|
40
|
+
onConfirm?.(new Date(e.nativeEvent.timestampMs), e.nativeEvent.confirmed);
|
|
41
41
|
}, [onConfirm]);
|
|
42
42
|
const handleClosed = useCallback(() => {
|
|
43
43
|
onClosed?.();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","StyleSheet","NativeDatePicker","jsx","_jsx","NO_DATE_SENTINEL","Number","MIN_SAFE_INTEGER","dateToMsOrSentinel","d","ms","getTime","isFinite","normalizeVisible","presentation","visible","undefined","DatePicker","props","style","date","minDate","maxDate","locale","timeZoneName","mode","onConfirm","onClosed","ios","android","testID","isModal","handleConfirm","e","Date","nativeEvent","timestampMs","handleClosed","nativeProps","styles","picker","dateMs","minDateMs","maxDateMs","preferredStyle","countDownDurationSeconds","minuteInterval","roundsToMinuteInterval","firstDayOfWeek","material","dialogTitle","positiveButtonTitle","negativeButtonTitle","create"],"sourceRoot":"../../src","sources":["DatePicker.tsx"],"mappings":";;AAAA;AACA,OAAOA,KAAK,IAAIC,WAAW,QAAQ,OAAO;AAE1C,SAASC,UAAU,QAAQ,cAAc;AAEzC,OAAOC,gBAAgB,MAShB,6BAA6B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AA+CrC;AACA;AACA,MAAMC,gBAAgB,GAAGC,MAAM,CAACC,gBAAgB;AAEhD,SAASC,kBAAkBA,CAACC,CAA0B,EAAU;EAC9D,IAAI,CAACA,CAAC,EAAE,OAAOJ,gBAAgB;EAC/B,MAAMK,EAAE,GAAGD,CAAC,CAACE,OAAO,CAAC,CAAC;EACtB,OAAOL,MAAM,CAACM,QAAQ,CAACF,EAAE,CAAC,GAAGA,EAAE,GAAGL,gBAAgB;AACpD;AAEA,SAASQ,gBAAgBA,CACvBC,YAA+D,EAC/DC,OAA4B,EACP;EACrB;EACA,IAAID,YAAY,KAAK,OAAO,EAAE,OAAOE,SAAS;EAC9C,OAAOD,OAAO,GAAG,MAAM,GAAG,QAAQ;AACpC;AAEA,OAAO,SAASE,UAAUA,CAACC,KAAsB,EAAsB;EACrE,MAAM;IACJC,KAAK;IACLC,IAAI;IACJC,OAAO;IACPC,OAAO;IACPC,MAAM;IACNC,YAAY;IACZC,IAAI;IACJX,YAAY,GAAG,OAAO;IACtBC,OAAO;IACPW,SAAS;IACTC,QAAQ;IACRC,GAAG;IACHC,OAAO;IACPC;EACF,CAAC,GAAGZ,KAAK;EAET,MAAMa,OAAO,GAAGjB,YAAY,KAAK,OAAO;EAExC,MAAMkB,aAAa,GAAGhC,WAAW,CAC9BiC,CAAwC,IAAK;IAC5CP,SAAS,GAAG,IAAIQ,IAAI,CAACD,CAAC,CAACE,WAAW,CAACC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["React","useCallback","StyleSheet","NativeDatePicker","jsx","_jsx","NO_DATE_SENTINEL","Number","MIN_SAFE_INTEGER","dateToMsOrSentinel","d","ms","getTime","isFinite","normalizeVisible","presentation","visible","undefined","DatePicker","props","style","date","minDate","maxDate","locale","timeZoneName","mode","onConfirm","onClosed","ios","android","testID","isModal","handleConfirm","e","Date","nativeEvent","timestampMs","confirmed","handleClosed","nativeProps","styles","picker","dateMs","minDateMs","maxDateMs","preferredStyle","countDownDurationSeconds","minuteInterval","roundsToMinuteInterval","firstDayOfWeek","material","dialogTitle","positiveButtonTitle","negativeButtonTitle","create"],"sourceRoot":"../../src","sources":["DatePicker.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// SelectionMenu.tsx
|
|
4
4
|
import React, { useCallback, useMemo } from 'react';
|
|
5
|
+
import { Platform } from 'react-native';
|
|
5
6
|
import NativeSelectionMenu from './SelectionMenuNativeComponent';
|
|
6
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
8
|
function normalizeSelectedData(selected) {
|
|
@@ -48,6 +49,10 @@ export function SelectionMenu(props) {
|
|
|
48
49
|
material: android.material
|
|
49
50
|
};
|
|
50
51
|
}, [android]);
|
|
52
|
+
|
|
53
|
+
// On Android, force a fresh native view when structural props change so the
|
|
54
|
+
// widget gets a clean measurement cycle (TextInputLayout caches aggressively).
|
|
55
|
+
const remountKey = Platform.OS === 'android' ? `${presentation}-${android?.material ?? 'system'}` : undefined;
|
|
51
56
|
return /*#__PURE__*/_jsx(NativeSelectionMenu, {
|
|
52
57
|
style: style,
|
|
53
58
|
options: options,
|
|
@@ -61,6 +66,6 @@ export function SelectionMenu(props) {
|
|
|
61
66
|
ios: ios,
|
|
62
67
|
android: nativeAndroid,
|
|
63
68
|
...viewProps
|
|
64
|
-
});
|
|
69
|
+
}, remountKey);
|
|
65
70
|
}
|
|
66
71
|
//# sourceMappingURL=SelectionMenu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useMemo","NativeSelectionMenu","jsx","_jsx","normalizeSelectedData","selected","normalizeNativeVisible","presentation","visible","undefined","SelectionMenu","props","style","options","disabled","placeholder","onSelect","onRequestClose","ios","android","viewProps","selectedData","nativeVisible","handleSelect","e","index","label","data","nativeEvent","handleRequestClose","nativeAndroid","material","interactivity","anchorMode"],"sourceRoot":"../../src","sources":["SelectionMenu.tsx"],"mappings":";;AAAA;AACA,OAAOA,KAAK,IAAIC,WAAW,EAAEC,OAAO,QAAQ,OAAO;
|
|
1
|
+
{"version":3,"names":["React","useCallback","useMemo","Platform","NativeSelectionMenu","jsx","_jsx","normalizeSelectedData","selected","normalizeNativeVisible","presentation","visible","undefined","SelectionMenu","props","style","options","disabled","placeholder","onSelect","onRequestClose","ios","android","viewProps","selectedData","nativeVisible","handleSelect","e","index","label","data","nativeEvent","handleRequestClose","nativeAndroid","material","remountKey","OS","interactivity","anchorMode"],"sourceRoot":"../../src","sources":["SelectionMenu.tsx"],"mappings":";;AAAA;AACA,OAAOA,KAAK,IAAIC,WAAW,EAAEC,OAAO,QAAQ,OAAO;AACnD,SAASC,QAAQ,QAAwB,cAAc;AAEvD,OAAOC,mBAAmB,MAGnB,gCAAgC;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAyDxC,SAASC,qBAAqBA,CAACC,QAAuB,EAAU;EAC9D,OAAOA,QAAQ,IAAI,EAAE;AACvB;AAEA,SAASC,sBAAsBA,CAC7BC,YAAsC,EACtCC,OAA4B,EACG;EAC/B;EACA,IAAID,YAAY,KAAK,UAAU,EAAE,OAAOE,SAAS;EACjD,OAAOD,OAAO,GAAG,MAAM,GAAG,QAAQ;AACpC;AAEA,OAAO,SAASE,aAAaA,CAACC,KAAyB,EAAsB;EAC3E,MAAM;IACJC,KAAK;IACLC,OAAO;IACPR,QAAQ;IACRS,QAAQ;IACRC,WAAW;IACXR,YAAY,GAAG,OAAO;IACtBC,OAAO;IACPQ,QAAQ;IACRC,cAAc;IACdC,GAAG;IACHC,OAAO;IACP,GAAGC;EACL,CAAC,GAAGT,KAAK;EAET,MAAMU,YAAY,GAAGtB,OAAO,CAC1B,MAAMK,qBAAqB,CAACC,QAAQ,CAAC,EACrC,CAACA,QAAQ,CACX,CAAC;EAED,MAAMiB,aAAa,GAAGvB,OAAO,CAC3B,MAAMO,sBAAsB,CAACC,YAAY,EAAEC,OAAO,CAAC,EACnD,CAACD,YAAY,EAAEC,OAAO,CACxB,CAAC;EAED,MAAMe,YAAY,GAAGzB,WAAW,CAC7B0B,CAA4C,IAAK;IAChD,MAAM;MAAEC,KAAK;MAAEC,KAAK;MAAEC;IAAK,CAAC,GAAGH,CAAC,CAACI,WAAW;IAC5CZ,QAAQ,GAAGW,IAAI,EAAED,KAAK,EAAED,KAAK,CAAC;EAChC,CAAC,EACD,CAACT,QAAQ,CACX,CAAC;EAED,MAAMa,kBAAkB,GAAG/B,WAAW,CAAC,MAAM;IAC3CmB,cAAc,GAAG,CAAC;EACpB,CAAC,EAAE,CAACA,cAAc,CAAC,CAAC;;EAEpB;EACA,MAAMa,aAAa,GAAG/B,OAAO,CAAC,MAAM;IAClC,IAAI,CAACoB,OAAO,EAAE,OAAOV,SAAS;IAC9B,OAAO;MAAEsB,QAAQ,EAAEZ,OAAO,CAACY;IAAS,CAAC;EACvC,CAAC,EAAE,CAACZ,OAAO,CAAC,CAAC;;EAEb;EACA;EACA,MAAMa,UAAU,GACdhC,QAAQ,CAACiC,EAAE,KAAK,SAAS,GACrB,GAAG1B,YAAY,IAAIY,OAAO,EAAEY,QAAQ,IAAI,QAAQ,EAAE,GAClDtB,SAAS;EAEf,oBACEN,IAAA,CAACF,mBAAmB;IAElBW,KAAK,EAAEA,KAAM;IACbC,OAAO,EAAEA,OAAQ;IACjBQ,YAAY,EAAEA,YAAa;IAC3Ba,aAAa,EAAEpB,QAAQ,GAAG,UAAU,GAAG,SAAU;IACjDC,WAAW,EAAEA,WAAY;IACzBoB,UAAU,EAAE5B,YAAY,KAAK,UAAU,GAAG,QAAQ,GAAG,UAAW;IAChEC,OAAO,EAAEc,aAAc;IACvBN,QAAQ,EAAEA,QAAQ,GAAGO,YAAY,GAAGd,SAAU;IAC9CQ,cAAc,EAAEA,cAAc,GAAGY,kBAAkB,GAAGpB,SAAU;IAChES,GAAG,EAAEA,GAAI;IACTC,OAAO,EAAEW,aAAc;IAAA,GACnBV;EAAS,GAZRY,UAaN,CAAC;AAEN","ignoreList":[]}
|
|
@@ -18,7 +18,7 @@ export type DatePickerProps = {
|
|
|
18
18
|
* Wrapper ergonomics: boolean.
|
|
19
19
|
*/
|
|
20
20
|
visible?: boolean;
|
|
21
|
-
onConfirm?: (dateTime: Date) => void;
|
|
21
|
+
onConfirm?: (dateTime: Date, confirmed: boolean) => void;
|
|
22
22
|
onClosed?: () => void;
|
|
23
23
|
/** Test identifier */
|
|
24
24
|
testID?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../../src/DatePicker.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAwB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAyB,EAGvB,KAAK,QAAQ,IAAI,cAAc,EAC/B,KAAK,YAAY,IAAI,kBAAkB,EACvC,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,mBAAmB,EAAW,MAAM,eAAe,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B,2DAA2D;IAC3D,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAElB,mDAAmD;IACnD,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,YAAY,CAAC,EAAE,sBAAsB,CAAC;IAEtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../../src/DatePicker.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAwB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAyB,EAGvB,KAAK,QAAQ,IAAI,cAAc,EAC/B,KAAK,YAAY,IAAI,kBAAkB,EACvC,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,mBAAmB,EAAW,MAAM,eAAe,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B,2DAA2D;IAC3D,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAElB,mDAAmD;IACnD,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,YAAY,CAAC,EAAE,sBAAsB,CAAC;IAEtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,GAAG,CAAC,EAAE;QACJ,cAAc,CAAC,EAAE,kBAAkB,CAAC;QACpC,wBAAwB,CAAC,EAAE,cAAc,CAAC,0BAA0B,CAAC,CAAC;QACtE,cAAc,CAAC,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;QAClD,sBAAsB,CAAC,EAAE,yBAAyB,CAAC;KACpD,CAAC;IAEF,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;QACtD,QAAQ,CAAC,EAAE,mBAAmB,CAAC;QAC/B,WAAW,CAAC,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAChD,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;QAChE,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;KACjE,CAAC;CACH,CAAC;AAqBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAqErE"}
|
|
@@ -2,6 +2,7 @@ import type { CodegenTypes, ViewProps } from 'react-native';
|
|
|
2
2
|
export type TimestampMs = CodegenTypes.Double;
|
|
3
3
|
export type DateChangeEvent = {
|
|
4
4
|
timestampMs: CodegenTypes.Double;
|
|
5
|
+
confirmed: boolean;
|
|
5
6
|
};
|
|
6
7
|
export type DatePickerMode = 'date' | 'time' | 'dateAndTime' | 'countDownTimer';
|
|
7
8
|
export type DatePickerPresentation = 'modal' | 'embedded';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePickerNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/DatePickerNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG5D,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"DatePickerNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/DatePickerNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG5D,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAChF,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1D,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC/E,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAExE,MAAM,MAAM,QAAQ,GAAG;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC;IAC/C,cAAc,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpC,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxC,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AAEtC;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,MAAM,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAClE,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,CAAC;IACrE,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAErE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,WAAW,WAAY,SAAQ,SAAS,EAAE,WAAW;IACzD,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,SAAS,CAAC,EAAE,YAAY,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAC/D,QAAQ,CAAC,EAAE,YAAY,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;CAC5D;;AAED,wBAAmE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionMenu.d.ts","sourceRoot":"","sources":["../../../../src/SelectionMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,
|
|
1
|
+
{"version":3,"file":"SelectionMenu.d.ts","sourceRoot":"","sources":["../../../../src/SelectionMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAExD,OAA4B,EAC1B,KAAK,mBAAmB,EAEzB,MAAM,gCAAgC,CAAC;AAExC,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,yCAAyC;IACzC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAExC;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhE;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,CAAC;IAET,OAAO,CAAC,EAAE;QACR,6CAA6C;QAC7C,QAAQ,CAAC,EAAE,mBAAmB,CAAC;KAChC,CAAC;IAEF,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAoE3E"}
|
|
@@ -18,7 +18,7 @@ export type DatePickerProps = {
|
|
|
18
18
|
* Wrapper ergonomics: boolean.
|
|
19
19
|
*/
|
|
20
20
|
visible?: boolean;
|
|
21
|
-
onConfirm?: (dateTime: Date) => void;
|
|
21
|
+
onConfirm?: (dateTime: Date, confirmed: boolean) => void;
|
|
22
22
|
onClosed?: () => void;
|
|
23
23
|
/** Test identifier */
|
|
24
24
|
testID?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../../src/DatePicker.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAwB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAyB,EAGvB,KAAK,QAAQ,IAAI,cAAc,EAC/B,KAAK,YAAY,IAAI,kBAAkB,EACvC,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,mBAAmB,EAAW,MAAM,eAAe,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B,2DAA2D;IAC3D,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAElB,mDAAmD;IACnD,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,YAAY,CAAC,EAAE,sBAAsB,CAAC;IAEtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../../src/DatePicker.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAwB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAyB,EAGvB,KAAK,QAAQ,IAAI,cAAc,EAC/B,KAAK,YAAY,IAAI,kBAAkB,EACvC,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,mBAAmB,EAAW,MAAM,eAAe,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B,2DAA2D;IAC3D,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAElB,mDAAmD;IACnD,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,YAAY,CAAC,EAAE,sBAAsB,CAAC;IAEtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,GAAG,CAAC,EAAE;QACJ,cAAc,CAAC,EAAE,kBAAkB,CAAC;QACpC,wBAAwB,CAAC,EAAE,cAAc,CAAC,0BAA0B,CAAC,CAAC;QACtE,cAAc,CAAC,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;QAClD,sBAAsB,CAAC,EAAE,yBAAyB,CAAC;KACpD,CAAC;IAEF,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;QACtD,QAAQ,CAAC,EAAE,mBAAmB,CAAC;QAC/B,WAAW,CAAC,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAChD,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;QAChE,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;KACjE,CAAC;CACH,CAAC;AAqBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAqErE"}
|
|
@@ -2,6 +2,7 @@ import type { CodegenTypes, ViewProps } from 'react-native';
|
|
|
2
2
|
export type TimestampMs = CodegenTypes.Double;
|
|
3
3
|
export type DateChangeEvent = {
|
|
4
4
|
timestampMs: CodegenTypes.Double;
|
|
5
|
+
confirmed: boolean;
|
|
5
6
|
};
|
|
6
7
|
export type DatePickerMode = 'date' | 'time' | 'dateAndTime' | 'countDownTimer';
|
|
7
8
|
export type DatePickerPresentation = 'modal' | 'embedded';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePickerNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/DatePickerNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG5D,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"DatePickerNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/DatePickerNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG5D,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAChF,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1D,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC/E,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAExE,MAAM,MAAM,QAAQ,GAAG;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC;IAC/C,cAAc,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpC,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxC,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AAEtC;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,MAAM,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAClE,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,CAAC;IACrE,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAErE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,WAAW,WAAY,SAAQ,SAAS,EAAE,WAAW;IACzD,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,SAAS,CAAC,EAAE,YAAY,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAC/D,QAAQ,CAAC,EAAE,YAAY,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;CAC5D;;AAED,wBAAmE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionMenu.d.ts","sourceRoot":"","sources":["../../../../src/SelectionMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,
|
|
1
|
+
{"version":3,"file":"SelectionMenu.d.ts","sourceRoot":"","sources":["../../../../src/SelectionMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAExD,OAA4B,EAC1B,KAAK,mBAAmB,EAEzB,MAAM,gCAAgC,CAAC;AAExC,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,yCAAyC;IACzC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAExC;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhE;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,CAAC;IAET,OAAO,CAAC,EAAE;QACR,6CAA6C;QAC7C,QAAQ,CAAC,EAAE,mBAAmB,CAAC;KAChC,CAAC;IAEF,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAoE3E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-platform-components",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.8",
|
|
4
4
|
"description": "Native UI components for React Native: DatePicker, ContextMenu, SelectionMenu, SegmentedControl, LiquidGlass.",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/module/index.js",
|
package/src/DatePicker.tsx
CHANGED
|
@@ -37,7 +37,7 @@ export type DatePickerProps = {
|
|
|
37
37
|
*/
|
|
38
38
|
visible?: boolean;
|
|
39
39
|
|
|
40
|
-
onConfirm?: (dateTime: Date) => void;
|
|
40
|
+
onConfirm?: (dateTime: Date, confirmed: boolean) => void;
|
|
41
41
|
onClosed?: () => void;
|
|
42
42
|
|
|
43
43
|
/** Test identifier */
|
|
@@ -100,7 +100,7 @@ export function DatePicker(props: DatePickerProps): React.ReactElement {
|
|
|
100
100
|
|
|
101
101
|
const handleConfirm = useCallback(
|
|
102
102
|
(e: NativeSyntheticEvent<DateChangeEvent>) => {
|
|
103
|
-
onConfirm?.(new Date(e.nativeEvent.timestampMs));
|
|
103
|
+
onConfirm?.(new Date(e.nativeEvent.timestampMs), e.nativeEvent.confirmed);
|
|
104
104
|
},
|
|
105
105
|
[onConfirm]
|
|
106
106
|
);
|
package/src/SelectionMenu.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SelectionMenu.tsx
|
|
2
2
|
import React, { useCallback, useMemo } from 'react';
|
|
3
|
-
import { type ViewProps } from 'react-native';
|
|
3
|
+
import { Platform, type ViewProps } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import NativeSelectionMenu, {
|
|
6
6
|
type SelectionMenuOption,
|
|
@@ -119,8 +119,16 @@ export function SelectionMenu(props: SelectionMenuProps): React.ReactElement {
|
|
|
119
119
|
return { material: android.material };
|
|
120
120
|
}, [android]);
|
|
121
121
|
|
|
122
|
+
// On Android, force a fresh native view when structural props change so the
|
|
123
|
+
// widget gets a clean measurement cycle (TextInputLayout caches aggressively).
|
|
124
|
+
const remountKey =
|
|
125
|
+
Platform.OS === 'android'
|
|
126
|
+
? `${presentation}-${android?.material ?? 'system'}`
|
|
127
|
+
: undefined;
|
|
128
|
+
|
|
122
129
|
return (
|
|
123
130
|
<NativeSelectionMenu
|
|
131
|
+
key={remountKey}
|
|
124
132
|
style={style}
|
|
125
133
|
options={options}
|
|
126
134
|
selectedData={selectedData}
|