react-native-platform-components 0.5.1 → 0.5.3

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
@@ -26,7 +26,6 @@
26
26
  </table>
27
27
  </td>
28
28
  <td valign="top">
29
- <blockquote>🚧 In development — not ready for public use.</blockquote>
30
29
  <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
30
  <p>This library focuses on <strong>true native behavior</strong>, not JavaScript re-implementations — providing:</p>
32
31
  <ul>
@@ -210,8 +210,12 @@ class PCDatePickerView(context: Context) : FrameLayout(context) {
210
210
  // Use spinner mode to avoid CalendarView rendering bugs when scrolling months
211
211
  calendarViewShown = false
212
212
  spinnersShown = true
213
- minDateMs?.let { minDate = it }
214
- maxDateMs?.let { maxDate = it }
213
+ // Defer min/max date setting to avoid CalendarView initialization race condition
214
+ // where SimpleMonthView may not be fully detached yet during layout
215
+ post {
216
+ minDateMs?.let { minDate = it }
217
+ maxDateMs?.let { maxDate = it }
218
+ }
215
219
  }
216
220
  container.addView(dp)
217
221
  inlineDatePicker = dp
@@ -387,18 +391,31 @@ class PCDatePickerView(context: Context) : FrameLayout(context) {
387
391
  val picker = DatePicker(act).apply {
388
392
  calendarViewShown = true
389
393
  spinnersShown = false
390
- minDateMs?.let { minDate = it }
391
- maxDateMs?.let { maxDate = it }
394
+ // Set the date first, before min/max constraints
392
395
  updateDate(
393
396
  cal.get(Calendar.YEAR),
394
397
  cal.get(Calendar.MONTH),
395
398
  cal.get(Calendar.DAY_OF_MONTH)
396
399
  )
400
+ // Defer min/max date setting to avoid CalendarView initialization race condition
401
+ // where SimpleMonthView may not be created yet during layout
402
+ post {
403
+ minDateMs?.let { minDate = it }
404
+ maxDateMs?.let { maxDate = it }
405
+ }
406
+ }
407
+
408
+ // Wrap picker in a container with horizontal padding to prevent CalendarView
409
+ // from clipping against the dialog edges
410
+ val container = FrameLayout(act).apply {
411
+ val horizontalPadding = (8 * resources.displayMetrics.density).toInt()
412
+ setPadding(horizontalPadding, 0, horizontalPadding, 0)
413
+ addView(picker)
397
414
  }
398
415
 
399
416
  val dlg = AlertDialog.Builder(act)
400
417
  .setTitle(androidDialogTitle ?: "")
401
- .setView(picker)
418
+ .setView(container)
402
419
  .setPositiveButton(androidPositiveTitle ?: "OK") { _, _ ->
403
420
  val c = calendarFor(ts)
404
421
  c.set(Calendar.YEAR, picker.year)
@@ -489,18 +506,31 @@ class PCDatePickerView(context: Context) : FrameLayout(context) {
489
506
  val picker = DatePicker(act).apply {
490
507
  calendarViewShown = true
491
508
  spinnersShown = false
492
- minDateMs?.let { minDate = it }
493
- maxDateMs?.let { maxDate = it }
509
+ // Set the date first, before min/max constraints
494
510
  updateDate(
495
511
  cal.get(Calendar.YEAR),
496
512
  cal.get(Calendar.MONTH),
497
513
  cal.get(Calendar.DAY_OF_MONTH)
498
514
  )
515
+ // Defer min/max date setting to avoid CalendarView initialization race condition
516
+ // where SimpleMonthView may not be created yet during layout
517
+ post {
518
+ minDateMs?.let { minDate = it }
519
+ maxDateMs?.let { maxDate = it }
520
+ }
521
+ }
522
+
523
+ // Wrap picker in a container with horizontal padding to prevent CalendarView
524
+ // from clipping against the dialog edges
525
+ val container = FrameLayout(act).apply {
526
+ val horizontalPadding = (8 * resources.displayMetrics.density).toInt()
527
+ setPadding(horizontalPadding, 0, horizontalPadding, 0)
528
+ addView(picker)
499
529
  }
500
530
 
501
531
  val dlg = AlertDialog.Builder(act)
502
532
  .setTitle(androidDialogTitle ?: "")
503
- .setView(picker)
533
+ .setView(container)
504
534
  .setPositiveButton(androidPositiveTitle ?: "Next") { _, _ ->
505
535
  val c = calendarFor(ts)
506
536
  c.set(Calendar.YEAR, picker.year)
@@ -417,6 +417,9 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
417
417
  suppressInlineSpinnerCallbacks(sp)
418
418
  sp.setSelection(target, false)
419
419
  }
420
+
421
+ // Update headless menu checked state
422
+ refreshHeadlessMenu()
420
423
  }
421
424
 
422
425
  // ---- Inline dropdown overlay ----
@@ -528,10 +531,13 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context) {
528
531
  }
529
532
 
530
533
  private fun refreshHeadlessMenu() {
531
- val menu = headlessMenu?.menu ?: return
534
+ val popup = headlessMenu ?: return
535
+ val menu = popup.menu
532
536
  menu.clear()
537
+ val selectedIdx = options.indexOfFirst { it.data == selectedData }
533
538
  options.forEachIndexed { index, opt ->
534
- menu.add(0, index, index, opt.label)
539
+ val label = if (index == selectedIdx) "✓ ${opt.label}" else " ${opt.label}"
540
+ menu.add(0, index, index, label)
535
541
  }
536
542
  }
537
543
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-platform-components",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
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",
@@ -47,7 +47,16 @@
47
47
  "keywords": [
48
48
  "react-native",
49
49
  "ios",
50
- "android"
50
+ "android",
51
+ "datepicker",
52
+ "date-picker",
53
+ "time-picker",
54
+ "picker",
55
+ "menu",
56
+ "selection-menu",
57
+ "dropdown",
58
+ "native",
59
+ "material-design"
51
60
  ],
52
61
  "repository": {
53
62
  "type": "git",