react-native-platform-components 0.5.0 → 0.5.1

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 CHANGED
@@ -5,39 +5,45 @@
5
5
 
6
6
  <table>
7
7
  <tr>
8
- <td align="center"><strong>iOS DatePicker</strong></td>
9
- <td align="center"><strong>Android DatePicker</strong></td>
10
- </tr>
11
- <tr>
12
- <td><video src="https://github.com/user-attachments/assets/a9fb6237-6078-496b-8a58-1f2fae4f1af5" height="400"></video></td>
13
- <td><video src="https://github.com/user-attachments/assets/70e42d98-7ea6-40fe-90c5-c1efc2227f25" height="400"></video></td>
14
- </tr>
15
- <tr>
16
- <td align="center"><strong>iOS SelectionMenu</strong></td>
17
- <td align="center"><strong>Android SelectionMenu</strong></td>
18
- </tr>
19
- <tr>
20
- <td><video src="https://github.com/user-attachments/assets/f1af8e91-4e98-4dbe-a2a6-57f91770678e" height="400"></video></td>
21
- <td><video src="https://github.com/user-attachments/assets/dc61da04-45e5-43c3-b766-6048367775bb" height="400"></video></td>
8
+ <td valign="top">
9
+ <table>
10
+ <tr>
11
+ <td align="center"><strong>iOS DatePicker</strong></td>
12
+ <td align="center"><strong>Android DatePicker</strong></td>
13
+ </tr>
14
+ <tr>
15
+ <td><img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/ios-datepicker.gif" height="350" /></td>
16
+ <td><img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/android-datepicker.gif" height="350" /></td>
17
+ </tr>
18
+ <tr>
19
+ <td align="center"><strong>iOS SelectionMenu</strong></td>
20
+ <td align="center"><strong>Android SelectionMenu</strong></td>
21
+ </tr>
22
+ <tr>
23
+ <td><img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/ios-selectionmenu.gif" height="350" /></td>
24
+ <td><img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/android-selectionmenu.gif" height="350" /></td>
25
+ </tr>
26
+ </table>
27
+ </td>
28
+ <td valign="top">
29
+ <blockquote>🚧 In development — not ready for public use.</blockquote>
30
+ <p>High-quality <strong>native UI components for React Native</strong>, implemented with platform-first APIs and exposed through clean, typed JavaScript interfaces.</p>
31
+ <p>This library focuses on <strong>true native behavior</strong>, not JavaScript re-implementations — providing:</p>
32
+ <ul>
33
+ <li><strong>SelectionMenu</strong> – native selection menus (Material on Android, system menus on iOS)</li>
34
+ <li><strong>DatePicker</strong> – native date & time pickers with modal and embedded presentations</li>
35
+ </ul>
36
+ <p>The goal is to provide components that:</p>
37
+ <ul>
38
+ <li>Feel <strong>100% native</strong> on each platform</li>
39
+ <li>Support modern platform design systems (Material 3 on Android, system pickers on iOS)</li>
40
+ <li>Offer <strong>headless</strong> and <strong>inline</strong> modes for maximum layout control</li>
41
+ <li>Integrate cleanly with <strong>React Native Codegen / Fabric</strong></li>
42
+ </ul>
43
+ </td>
22
44
  </tr>
23
45
  </table>
24
46
 
25
- > 🚧 In development — not ready for public use.
26
-
27
- High-quality **native UI components for React Native**, implemented with platform-first APIs and exposed through clean, typed JavaScript interfaces.
28
-
29
- This library focuses on **true native behavior**, not JavaScript re-implementations — providing:
30
-
31
- - **SelectionMenu** – native selection menus (Material on Android, system menus on iOS)
32
- - **DatePicker** – native date & time pickers with modal and embedded presentations
33
-
34
- The goal is to provide components that:
35
-
36
- - Feel **100% native** on each platform
37
- - Support modern platform design systems (Material 3 on Android, system pickers on iOS)
38
- - Offer **headless** and **inline** modes for maximum layout control
39
- - Integrate cleanly with **React Native Codegen / Fabric**
40
-
41
47
  ---
42
48
 
43
49
  ## Installation
@@ -51,6 +51,7 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
51
51
  private var headlessMenuShowing = false
52
52
  private var headlessDismissProgrammatic = false
53
53
  private var headlessDismissAfterSelect = false
54
+ private var headlessOpenToken = 0
54
55
 
55
56
  init {
56
57
  minimumHeight = 0
@@ -129,6 +130,13 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
129
130
  if (anchorMode == newMode) return
130
131
  anchorMode = newMode
131
132
  Log.d(TAG, "applyAnchorMode anchorMode=$anchorMode")
133
+ if (anchorMode != "headless") {
134
+ headlessOpenToken += 1
135
+ if (headlessMenuShowing) {
136
+ headlessDismissProgrammatic = true
137
+ headlessMenu?.dismiss()
138
+ }
139
+ }
132
140
  rebuildUI()
133
141
  }
134
142
 
@@ -138,11 +146,13 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
138
146
  else -> "closed"
139
147
  }
140
148
  Log.d(TAG, "applyVisible visible=$visible anchorMode=$anchorMode")
149
+ headlessOpenToken += 1
150
+ val token = headlessOpenToken
141
151
 
142
152
  if (anchorMode != "headless") return
143
153
 
144
154
  if (visible == "open") {
145
- presentHeadlessIfNeeded()
155
+ presentHeadlessIfNeeded(token)
146
156
  } else {
147
157
  Log.d(TAG, "applyVisible close -> dismiss")
148
158
  if (headlessMenuShowing) {
@@ -162,6 +172,10 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
162
172
  // ---- UI building ----
163
173
 
164
174
  private fun rebuildUI() {
175
+ if (headlessMenuShowing) {
176
+ headlessDismissProgrammatic = true
177
+ headlessMenu?.dismiss()
178
+ }
165
179
  inlineText?.dismissDropDown()
166
180
  detachInlineDropdownOverlay()
167
181
  inlineDropdownOverlay = null
@@ -465,7 +479,7 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
465
479
 
466
480
  // ---- Headless open ----
467
481
 
468
- private fun presentHeadlessIfNeeded() {
482
+ private fun presentHeadlessIfNeeded(token: Int) {
469
483
  val popup = headlessMenu ?: return
470
484
  if (interactivity != "enabled") {
471
485
  Log.d(TAG, "presentHeadlessIfNeeded interactivity=$interactivity -> requestClose")
@@ -473,6 +487,18 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
473
487
  return
474
488
  }
475
489
  post {
490
+ if (token != headlessOpenToken) {
491
+ Log.d(TAG, "presentHeadlessIfNeeded stale token -> skip")
492
+ return@post
493
+ }
494
+ if (anchorMode != "headless" || visible != "open") {
495
+ Log.d(TAG, "presentHeadlessIfNeeded no longer open -> skip")
496
+ return@post
497
+ }
498
+ if (interactivity != "enabled") {
499
+ Log.d(TAG, "presentHeadlessIfNeeded disabled -> skip")
500
+ return@post
501
+ }
476
502
  if (!isAttachedToWindow) {
477
503
  Log.d(TAG, "presentHeadlessIfNeeded not attached -> requestClose")
478
504
  onRequestClose?.invoke()
@@ -98,6 +98,8 @@ public final class PCSelectionMenuView: UIControl {
98
98
  private let model = PCSelectionMenuModel()
99
99
  private var hostingController: UIHostingController<AnyView>?
100
100
  private var headlessMenuView: UIView?
101
+ private var headlessMenuVC: UIViewController?
102
+ private var headlessPresentationToken: Int = 0
101
103
 
102
104
  private var parsedOptions: [PCSelectionMenuOption] {
103
105
  options.compactMap { any in
@@ -132,12 +134,16 @@ public final class PCSelectionMenuView: UIControl {
132
134
  alpha = disabled ? 0.5 : 1.0
133
135
  isUserInteractionEnabled = !disabled
134
136
  accessibilityTraits = disabled ? [.notEnabled] : [.button]
137
+ if disabled {
138
+ dismissHeadlessIfNeeded()
139
+ }
135
140
  }
136
141
 
137
142
  // MARK: - Inline vs headless
138
143
 
139
144
  private func updateAnchorMode() {
140
145
  if anchorMode == "inline" {
146
+ dismissHeadlessIfNeeded()
141
147
  uninstallHeadlessIfNeeded()
142
148
  installInlineIfNeeded()
143
149
  sync()
@@ -248,15 +254,22 @@ public final class PCSelectionMenuView: UIControl {
248
254
 
249
255
  private func updatePresentation() {
250
256
  guard anchorMode != "inline" else { return }
251
- guard interactivity != "disabled" else { return }
257
+ headlessPresentationToken += 1
252
258
 
253
- if visible == "open" {
254
- presentHeadlessMenuIfNeeded()
259
+ if visible == "open" && interactivity != "disabled" {
260
+ presentHeadlessMenuIfNeeded(token: headlessPresentationToken)
261
+ } else {
262
+ dismissHeadlessIfNeeded()
255
263
  }
256
- // Note: dismissal is handled by the menu itself calling onRequestClose
257
264
  }
258
265
 
259
- private func presentHeadlessMenuIfNeeded() {
266
+ private func dismissHeadlessIfNeeded() {
267
+ guard let vc = headlessMenuVC else { return }
268
+ headlessMenuVC = nil
269
+ vc.dismiss(animated: true)
270
+ }
271
+
272
+ private func presentHeadlessMenuIfNeeded(token: Int) {
260
273
  guard headlessMenuView != nil else { return }
261
274
  guard let vc = nearestViewController() else { return }
262
275
 
@@ -264,7 +277,15 @@ public final class PCSelectionMenuView: UIControl {
264
277
  guard !opts.isEmpty else { return }
265
278
 
266
279
  logger.debug("presentHeadlessMenuIfNeeded: scheduling presentation with \(opts.count) options")
267
- DispatchQueue.main.asyncAfter(deadline: .now() + PCConstants.headlessPresentationDelay) {
280
+ DispatchQueue.main.asyncAfter(deadline: .now() + PCConstants.headlessPresentationDelay) { [weak self] in
281
+ guard let self else { return }
282
+ guard self.headlessPresentationToken == token else { return }
283
+ guard self.visible == "open" else { return }
284
+ guard self.anchorMode != "inline" else { return }
285
+ guard self.interactivity != "disabled" else { return }
286
+ guard self.headlessMenuVC == nil else { return }
287
+ guard self.window != nil else { return }
288
+
268
289
  let menuVC = PCMenuViewController(
269
290
  options: opts,
270
291
  onSelect: { [weak self] idx in
@@ -277,6 +298,9 @@ public final class PCSelectionMenuView: UIControl {
277
298
  onCancel: { [weak self] in
278
299
  logger.debug("headless menu cancelled")
279
300
  self?.onRequestClose?()
301
+ },
302
+ onDismiss: { [weak self] in
303
+ self?.headlessMenuVC = nil
280
304
  }
281
305
  )
282
306
 
@@ -317,6 +341,7 @@ public final class PCSelectionMenuView: UIControl {
317
341
  menuVC.modalTransitionStyle = .crossDissolve
318
342
  menuVC.menuFrame = menuFrame
319
343
 
344
+ self.headlessMenuVC = menuVC
320
345
  vc.present(menuVC, animated: true)
321
346
  }
322
347
  }
@@ -377,15 +402,22 @@ private class PCMenuViewController: UIViewController, UITableViewDelegate, UITab
377
402
  private let options: [PCSelectionMenuOption]
378
403
  private let onSelect: (Int) -> Void
379
404
  private let onCancel: () -> Void
405
+ private let onDismiss: () -> Void
380
406
  private var tableView: UITableView!
381
407
  private var menuContainer: UIView!
382
408
 
383
409
  var menuFrame: CGRect = .zero
384
410
 
385
- init(options: [PCSelectionMenuOption], onSelect: @escaping (Int) -> Void, onCancel: @escaping () -> Void) {
411
+ init(
412
+ options: [PCSelectionMenuOption],
413
+ onSelect: @escaping (Int) -> Void,
414
+ onCancel: @escaping () -> Void,
415
+ onDismiss: @escaping () -> Void
416
+ ) {
386
417
  self.options = options
387
418
  self.onSelect = onSelect
388
419
  self.onCancel = onCancel
420
+ self.onDismiss = onDismiss
389
421
  super.init(nibName: nil, bundle: nil)
390
422
  }
391
423
 
@@ -439,6 +471,11 @@ private class PCMenuViewController: UIViewController, UITableViewDelegate, UITab
439
471
  effectView.contentView.addSubview(tableView)
440
472
  }
441
473
 
474
+ override func viewDidDisappear(_ animated: Bool) {
475
+ super.viewDidDisappear(animated)
476
+ onDismiss()
477
+ }
478
+
442
479
  @objc private func handleBackgroundTap(_ gesture: UITapGestureRecognizer) {
443
480
  let location = gesture.location(in: view)
444
481
  if !menuContainer.frame.contains(location) {
@@ -465,4 +502,3 @@ private class PCMenuViewController: UIViewController, UITableViewDelegate, UITab
465
502
  }
466
503
  }
467
504
  }
468
-
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  // DatePicker.tsx
4
- import React, { useCallback, useMemo } from 'react';
4
+ import React, { useCallback } from 'react';
5
5
  import { StyleSheet } from 'react-native';
6
6
  import NativeDatePicker from './DatePickerNativeComponent';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -9,7 +9,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
9
9
  // conflict with valid negative timestamps (dates before 1970).
10
10
  const NO_DATE_SENTINEL = Number.MIN_SAFE_INTEGER;
11
11
  function dateToMsOrSentinel(d) {
12
- return d ? d.getTime() : NO_DATE_SENTINEL;
12
+ if (!d) return NO_DATE_SENTINEL;
13
+ const ms = d.getTime();
14
+ return Number.isFinite(ms) ? ms : NO_DATE_SENTINEL;
13
15
  }
14
16
  function normalizeVisible(presentation, visible) {
15
17
  // Only meaningful in modal presentation. Keep undefined for inline to avoid noise.
@@ -33,13 +35,13 @@ export function DatePicker(props) {
33
35
  android,
34
36
  testID
35
37
  } = props;
38
+ const isModal = presentation === 'modal';
36
39
  const handleConfirm = useCallback(e => {
37
40
  onConfirm?.(new Date(e.nativeEvent.timestampMs));
38
41
  }, [onConfirm]);
39
42
  const handleClosed = useCallback(() => {
40
43
  onClosed?.();
41
44
  }, [onClosed]);
42
- const styles = useMemo(() => createStyles(), []);
43
45
  const nativeProps = {
44
46
  style: [styles.picker, style],
45
47
  mode,
@@ -48,10 +50,10 @@ export function DatePicker(props) {
48
50
  presentation,
49
51
  visible: normalizeVisible(presentation, visible),
50
52
  dateMs: dateToMsOrSentinel(date),
51
- minDateMs: dateToMsOrSentinel(minDate ?? null),
52
- maxDateMs: dateToMsOrSentinel(maxDate ?? null),
53
+ minDateMs: dateToMsOrSentinel(minDate),
54
+ maxDateMs: dateToMsOrSentinel(maxDate),
53
55
  onConfirm: onConfirm ? handleConfirm : undefined,
54
- onClosed: onClosed ? handleClosed : undefined,
56
+ onClosed: isModal && onClosed ? handleClosed : undefined,
55
57
  ios: ios ? {
56
58
  preferredStyle: ios.preferredStyle,
57
59
  countDownDurationSeconds: ios.countDownDurationSeconds,
@@ -71,9 +73,7 @@ export function DatePicker(props) {
71
73
  ...nativeProps
72
74
  });
73
75
  }
74
- function createStyles() {
75
- return StyleSheet.create({
76
- picker: {}
77
- });
78
- }
76
+ const styles = StyleSheet.create({
77
+ picker: {}
78
+ });
79
79
  //# sourceMappingURL=DatePicker.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useMemo","StyleSheet","NativeDatePicker","jsx","_jsx","NO_DATE_SENTINEL","Number","MIN_SAFE_INTEGER","dateToMsOrSentinel","d","getTime","normalizeVisible","presentation","visible","undefined","DatePicker","props","style","date","minDate","maxDate","locale","timeZoneName","mode","onConfirm","onClosed","ios","android","testID","handleConfirm","e","Date","nativeEvent","timestampMs","handleClosed","styles","createStyles","nativeProps","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":[]}
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":"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","ignoreList":[]}
@@ -35,14 +35,15 @@ export type MacOSProps = Readonly<{}>;
35
35
 
36
36
  /**
37
37
  * Sentinel convention:
38
- * - `-1` means "no value / unbounded / unset".
38
+ * - `Number.MIN_SAFE_INTEGER` means "no value / unbounded / unset".
39
+ * (Allows negative timestamps for pre-1970 dates.)
39
40
  */
40
41
  export type CommonProps = {
41
42
  mode?: string; // DatePickerMode
42
43
 
43
- dateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
44
- minDateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
45
- maxDateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
44
+ dateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
45
+ minDateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
46
+ maxDateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
46
47
 
47
48
  locale?: string;
48
49
  timeZoneName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/DatePicker.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,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;IACrC,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;AAmBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAqErE"}
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;IACrC,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"}
@@ -25,13 +25,14 @@ export type WindowsProps = Readonly<{}>;
25
25
  export type MacOSProps = Readonly<{}>;
26
26
  /**
27
27
  * Sentinel convention:
28
- * - `-1` means "no value / unbounded / unset".
28
+ * - `Number.MIN_SAFE_INTEGER` means "no value / unbounded / unset".
29
+ * (Allows negative timestamps for pre-1970 dates.)
29
30
  */
30
31
  export type CommonProps = {
31
32
  mode?: string;
32
- dateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
33
- minDateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
34
- maxDateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
33
+ dateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
34
+ minDateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
35
+ maxDateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
35
36
  locale?: string;
36
37
  timeZoneName?: string;
37
38
  /**
@@ -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;CAClC,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;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,MAAM,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACnD,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtD,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
+ {"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;CAClC,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-platform-components",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "A cross-platform toolkit of native UI components for React Native.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -1,5 +1,5 @@
1
1
  #include <react/renderer/core/LayoutConstraints.h>
2
- #include "PCSelectionMenuShadowNode-Custom.h"
2
+ #include "PCSelectionMenuShadowNode-custom.h"
3
3
 
4
4
  #include <algorithm>
5
5
 
@@ -1,5 +1,5 @@
1
1
  // DatePicker.tsx
2
- import React, { useCallback, useMemo } from 'react';
2
+ import React, { useCallback } from 'react';
3
3
  import type { NativeSyntheticEvent, StyleProp, ViewStyle } from 'react-native';
4
4
  import { StyleSheet } from 'react-native';
5
5
 
@@ -64,7 +64,9 @@ export type DatePickerProps = {
64
64
  const NO_DATE_SENTINEL = Number.MIN_SAFE_INTEGER;
65
65
 
66
66
  function dateToMsOrSentinel(d: Date | null | undefined): number {
67
- return d ? d.getTime() : NO_DATE_SENTINEL;
67
+ if (!d) return NO_DATE_SENTINEL;
68
+ const ms = d.getTime();
69
+ return Number.isFinite(ms) ? ms : NO_DATE_SENTINEL;
68
70
  }
69
71
 
70
72
  function normalizeVisible(
@@ -94,6 +96,8 @@ export function DatePicker(props: DatePickerProps): React.ReactElement {
94
96
  testID,
95
97
  } = props;
96
98
 
99
+ const isModal = presentation === 'modal';
100
+
97
101
  const handleConfirm = useCallback(
98
102
  (e: NativeSyntheticEvent<DateChangeEvent>) => {
99
103
  onConfirm?.(new Date(e.nativeEvent.timestampMs));
@@ -105,24 +109,22 @@ export function DatePicker(props: DatePickerProps): React.ReactElement {
105
109
  onClosed?.();
106
110
  }, [onClosed]);
107
111
 
108
- const styles = useMemo(() => createStyles(), []);
109
-
110
112
  const nativeProps: NativeDatePickerProps = {
111
- style: [styles.picker, style] as any,
113
+ style: [styles.picker, style],
112
114
 
113
115
  mode,
114
116
  locale,
115
117
  timeZoneName,
116
118
 
117
119
  presentation,
118
- visible: normalizeVisible(presentation, visible) as any,
120
+ visible: normalizeVisible(presentation, visible),
119
121
 
120
- dateMs: dateToMsOrSentinel(date) as any,
121
- minDateMs: dateToMsOrSentinel(minDate ?? null) as any,
122
- maxDateMs: dateToMsOrSentinel(maxDate ?? null) as any,
122
+ dateMs: dateToMsOrSentinel(date),
123
+ minDateMs: dateToMsOrSentinel(minDate),
124
+ maxDateMs: dateToMsOrSentinel(maxDate),
123
125
 
124
126
  onConfirm: onConfirm ? handleConfirm : undefined,
125
- onClosed: onClosed ? handleClosed : undefined,
127
+ onClosed: isModal && onClosed ? handleClosed : undefined,
126
128
 
127
129
  ios: ios
128
130
  ? {
@@ -136,7 +138,7 @@ export function DatePicker(props: DatePickerProps): React.ReactElement {
136
138
  android: android
137
139
  ? {
138
140
  firstDayOfWeek: android.firstDayOfWeek,
139
- material: android.material as any,
141
+ material: android.material,
140
142
  dialogTitle: android.dialogTitle,
141
143
  positiveButtonTitle: android.positiveButtonTitle,
142
144
  negativeButtonTitle: android.negativeButtonTitle,
@@ -147,8 +149,6 @@ export function DatePicker(props: DatePickerProps): React.ReactElement {
147
149
  return <NativeDatePicker testID={testID} {...nativeProps} />;
148
150
  }
149
151
 
150
- function createStyles() {
151
- return StyleSheet.create({
152
- picker: {},
153
- });
154
- }
152
+ const styles = StyleSheet.create({
153
+ picker: {},
154
+ });
@@ -35,14 +35,15 @@ export type MacOSProps = Readonly<{}>;
35
35
 
36
36
  /**
37
37
  * Sentinel convention:
38
- * - `-1` means "no value / unbounded / unset".
38
+ * - `Number.MIN_SAFE_INTEGER` means "no value / unbounded / unset".
39
+ * (Allows negative timestamps for pre-1970 dates.)
39
40
  */
40
41
  export type CommonProps = {
41
42
  mode?: string; // DatePickerMode
42
43
 
43
- dateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
44
- minDateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
45
- maxDateMs?: CodegenTypes.WithDefault<TimestampMs, -1>;
44
+ dateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
45
+ minDateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
46
+ maxDateMs?: CodegenTypes.WithDefault<TimestampMs, -9007199254740991>;
46
47
 
47
48
  locale?: string;
48
49
  timeZoneName?: string;