react-native-platform-components 0.8.0 → 0.8.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.
Files changed (2) hide show
  1. package/README.md +158 -128
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -7,6 +7,8 @@ High-quality **native UI components for React Native**, implemented with platfor
7
7
 
8
8
  This library focuses on **true native behavior**, not JavaScript re-implementations.
9
9
 
10
+ **Have a component request?** If there's a native UI component you'd like to see added, [open an issue](https://github.com/JarX-Concepts/react-native-platform-components/issues/new) describing the component and its native APIs on iOS and Android.
11
+
10
12
  <table>
11
13
  <tr>
12
14
  <td align="center"><strong>iOS DatePicker</strong></td>
@@ -115,12 +117,11 @@ eas build --platform android
115
117
  **Config Plugin:**
116
118
 
117
119
  Add to your `app.json`:
120
+
118
121
  ```json
119
122
  {
120
123
  "expo": {
121
- "plugins": [
122
- ["react-native-platform-components/app.plugin", {}]
123
- ]
124
+ "plugins": [["react-native-platform-components/app.plugin", {}]]
124
125
  }
125
126
  }
126
127
  ```
@@ -133,18 +134,20 @@ For a complete working example, see the [`example-expo/`](./example-expo) direct
133
134
 
134
135
  This library is built for the **React Native New Architecture** (Fabric + TurboModules).
135
136
 
136
- | Feature | Status |
137
- |---------|--------|
138
- | Fabric (New Renderer) | Supported |
139
- | Codegen | Used for type-safe native bindings |
140
- | TurboModules | N/A (view components only) |
141
- | Old Architecture | Not supported |
137
+ | Feature | Status |
138
+ | --------------------- | ---------------------------------- |
139
+ | Fabric (New Renderer) | Supported |
140
+ | Codegen | Used for type-safe native bindings |
141
+ | TurboModules | N/A (view components only) |
142
+ | Old Architecture | Not supported |
142
143
 
143
144
  **Tested with:**
145
+
144
146
  - React Native 0.81+ (bare and Expo)
145
147
  - Expo SDK 54+
146
148
 
147
149
  **Requirements:**
150
+
148
151
  - New Architecture must be enabled in your app
149
152
  - For bare React Native: set `newArchEnabled=true` in `gradle.properties` (Android) and use the `RCT_NEW_ARCH_ENABLED` flag (iOS)
150
153
  - For Expo: set `"newArchEnabled": true` in `app.json`
@@ -176,8 +179,8 @@ export function Example() {
176
179
  setVisible(false);
177
180
  }}
178
181
  onClosed={() => setVisible(false)}
179
- ios={{preferredStyle: 'inline'}}
180
- android={{material: 'system'}}
182
+ ios={{ preferredStyle: 'inline' }}
183
+ android={{ material: 'system' }}
181
184
  />
182
185
  </>
183
186
  );
@@ -198,8 +201,8 @@ export function Example() {
198
201
  presentation="embedded"
199
202
  mode="date"
200
203
  onConfirm={(d) => setDate(d)}
201
- ios={{preferredStyle: 'inline'}}
202
- android={{material: 'system'}}
204
+ ios={{ preferredStyle: 'inline' }}
205
+ android={{ material: 'system' }}
203
206
  />
204
207
  );
205
208
  }
@@ -239,7 +242,9 @@ export function Example() {
239
242
  ]}
240
243
  onPressAction={(id, title) => setLastAction(title)}
241
244
  >
242
- <View style={{ padding: 20, backgroundColor: '#E8F4FD', borderRadius: 8 }}>
245
+ <View
246
+ style={{ padding: 20, backgroundColor: '#E8F4FD', borderRadius: 8 }}
247
+ >
243
248
  <Text>Long-press me</Text>
244
249
  </View>
245
250
  </ContextMenu>
@@ -400,18 +405,30 @@ export function Example() {
400
405
  ### LiquidGlass
401
406
 
402
407
  ```tsx
403
- import { LiquidGlass, isLiquidGlassSupported } from 'react-native-platform-components';
408
+ import {
409
+ LiquidGlass,
410
+ isLiquidGlassSupported,
411
+ } from 'react-native-platform-components';
404
412
  import { View, Text, Image } from 'react-native';
405
413
 
406
414
  export function Example() {
407
415
  return (
408
416
  <View style={{ flex: 1 }}>
409
417
  {/* Background content */}
410
- <Image source={{ uri: 'https://example.com/photo.jpg' }} style={{ flex: 1 }} />
418
+ <Image
419
+ source={{ uri: 'https://example.com/photo.jpg' }}
420
+ style={{ flex: 1 }}
421
+ />
411
422
 
412
423
  {/* Glass effect overlay */}
413
424
  <LiquidGlass
414
- style={{ position: 'absolute', top: 50, left: 20, right: 20, padding: 20 }}
425
+ style={{
426
+ position: 'absolute',
427
+ top: 50,
428
+ left: 20,
429
+ right: 20,
430
+ padding: 20,
431
+ }}
415
432
  cornerRadius={20}
416
433
  ios={{
417
434
  effect: 'regular',
@@ -441,37 +458,37 @@ Native date & time picker using **platform system pickers**.
441
458
 
442
459
  ### Props
443
460
 
444
- | Prop | Type | Description |
445
- |------|------|-------------|
446
- | `date` | `Date \| null` | Controlled date value |
447
- | `minDate` | `Date \| null` | Minimum selectable date |
448
- | `maxDate` | `Date \| null` | Maximum selectable date |
449
- | `locale` | `string` | Locale identifier (e.g., `'en-US'`) |
450
- | `timeZoneName` | `string` | Time zone identifier |
451
- | `mode` | `'date' \| 'time' \| 'dateAndTime' \| 'countDownTimer'` | Picker mode |
452
- | `presentation` | `'modal' \| 'embedded'` | Presentation style |
453
- | `visible` | `boolean` | Controls modal visibility (modal mode only) |
454
- | `onConfirm` | `(date: Date) => void` | Called when user confirms selection |
455
- | `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) => void` | Called when user confirms selection |
472
+ | `onClosed` | `() => void` | Called when modal is dismissed |
456
473
 
457
474
  ### iOS Props (`ios`)
458
475
 
459
- | Prop | Type | Description |
460
- |------|------|-------------|
461
- | `preferredStyle` | `'automatic' \| 'compact' \| 'inline' \| 'wheels'` | iOS date picker style |
462
- | `countDownDurationSeconds` | `number` | Duration for countdown timer mode |
463
- | `minuteInterval` | `number` | Minute interval (1-30) |
464
- | `roundsToMinuteInterval` | `'inherit' \| 'round' \| 'noRound'` | Rounding behavior |
476
+ | Prop | Type | Description |
477
+ | -------------------------- | -------------------------------------------------- | --------------------------------- |
478
+ | `preferredStyle` | `'automatic' \| 'compact' \| 'inline' \| 'wheels'` | iOS date picker style |
479
+ | `countDownDurationSeconds` | `number` | Duration for countdown timer mode |
480
+ | `minuteInterval` | `number` | Minute interval (1-30) |
481
+ | `roundsToMinuteInterval` | `'inherit' \| 'round' \| 'noRound'` | Rounding behavior |
465
482
 
466
483
  ### Android Props (`android`)
467
484
 
468
- | Prop | Type | Description |
469
- |------|------|-------------|
470
- | `firstDayOfWeek` | `number` | First day of week (1-7, Sunday=1) |
471
- | `material` | `'system' \| 'm3'` | Material Design style (modal only; embedded always uses system picker) |
472
- | `dialogTitle` | `string` | Custom dialog title |
473
- | `positiveButtonTitle` | `string` | Custom confirm button text |
474
- | `negativeButtonTitle` | `string` | Custom cancel button text |
485
+ | Prop | Type | Description |
486
+ | --------------------- | ------------------ | ---------------------------------------------------------------------- |
487
+ | `firstDayOfWeek` | `number` | First day of week (1-7, Sunday=1) |
488
+ | `material` | `'system' \| 'm3'` | Material Design style (modal only; embedded always uses system picker) |
489
+ | `dialogTitle` | `string` | Custom dialog title |
490
+ | `positiveButtonTitle` | `string` | Custom confirm button text |
491
+ | `negativeButtonTitle` | `string` | Custom cancel button text |
475
492
 
476
493
  ---
477
494
 
@@ -481,42 +498,42 @@ Native context menu that wraps content and responds to **long-press** or **tap**
481
498
 
482
499
  ### Props
483
500
 
484
- | Prop | Type | Description |
485
- |------|------|-------------|
486
- | `title` | `string` | Menu title (shown as header on iOS) |
487
- | `actions` | `ContextMenuAction[]` | Array of menu actions |
488
- | `disabled` | `boolean` | Disables the menu |
489
- | `trigger` | `'longPress' \| 'tap'` | How the menu opens (default: `'longPress'`) |
490
- | `onPressAction` | `(actionId, actionTitle) => void` | Called when user selects an action |
491
- | `onMenuOpen` | `() => void` | Called when menu opens |
492
- | `onMenuClose` | `() => void` | Called when menu closes |
493
- | `children` | `ReactNode` | Content to wrap (required) |
501
+ | Prop | Type | Description |
502
+ | --------------- | --------------------------------- | ------------------------------------------- |
503
+ | `title` | `string` | Menu title (shown as header on iOS) |
504
+ | `actions` | `ContextMenuAction[]` | Array of menu actions |
505
+ | `disabled` | `boolean` | Disables the menu |
506
+ | `trigger` | `'longPress' \| 'tap'` | How the menu opens (default: `'longPress'`) |
507
+ | `onPressAction` | `(actionId, actionTitle) => void` | Called when user selects an action |
508
+ | `onMenuOpen` | `() => void` | Called when menu opens |
509
+ | `onMenuClose` | `() => void` | Called when menu closes |
510
+ | `children` | `ReactNode` | Content to wrap (required) |
494
511
 
495
512
  ### ContextMenuAction
496
513
 
497
- | Property | Type | Description |
498
- |----------|------|-------------|
499
- | `id` | `string` | Unique identifier returned in callbacks |
500
- | `title` | `string` | Display text |
501
- | `subtitle` | `string` | Secondary text (iOS only) |
502
- | `image` | `string` | Icon name (SF Symbol on iOS, drawable on Android) |
503
- | `imageColor` | `string` | Tint color for the icon (hex string) |
504
- | `attributes` | `{ destructive?, disabled?, hidden? }` | Action attributes |
505
- | `state` | `'off' \| 'on' \| 'mixed'` | Checkmark state |
506
- | `subactions` | `ContextMenuAction[]` | Nested actions for submenu |
514
+ | Property | Type | Description |
515
+ | ------------ | -------------------------------------- | ------------------------------------------------- |
516
+ | `id` | `string` | Unique identifier returned in callbacks |
517
+ | `title` | `string` | Display text |
518
+ | `subtitle` | `string` | Secondary text (iOS only) |
519
+ | `image` | `string` | Icon name (SF Symbol on iOS, drawable on Android) |
520
+ | `imageColor` | `string` | Tint color for the icon (hex string) |
521
+ | `attributes` | `{ destructive?, disabled?, hidden? }` | Action attributes |
522
+ | `state` | `'off' \| 'on' \| 'mixed'` | Checkmark state |
523
+ | `subactions` | `ContextMenuAction[]` | Nested actions for submenu |
507
524
 
508
525
  ### iOS Props (`ios`)
509
526
 
510
- | Prop | Type | Description |
511
- |------|------|-------------|
527
+ | Prop | Type | Description |
528
+ | --------------- | --------- | --------------------------------- |
512
529
  | `enablePreview` | `boolean` | Enable preview when long-pressing |
513
530
 
514
531
  ### Android Props (`android`)
515
532
 
516
- | Prop | Type | Description |
517
- |------|------|-------------|
518
- | `anchorPosition` | `'left' \| 'right'` | Anchor position for the popup menu |
519
- | `visible` | `boolean` | Programmatic visibility control (Android only) |
533
+ | Prop | Type | Description |
534
+ | ---------------- | ------------------- | ---------------------------------------------- |
535
+ | `anchorPosition` | `'left' \| 'right'` | Anchor position for the popup menu |
536
+ | `visible` | `boolean` | Programmatic visibility control (Android only) |
520
537
 
521
538
  ### Trigger Modes
522
539
 
@@ -537,17 +554,17 @@ Native selection menu with **modal** and **embedded** modes.
537
554
 
538
555
  ### Props
539
556
 
540
- | Prop | Type | Description |
541
- |------|------|-------------|
542
- | `options` | `{ label: string; data: string }[]` | Array of options to display |
543
- | `selected` | `string \| null` | Currently selected option's `data` value |
544
- | `disabled` | `boolean` | Disables the menu |
545
- | `placeholder` | `string` | Placeholder text when no selection |
546
- | `presentation` | `'modal' \| 'embedded'` | Presentation mode (default: `'modal'`) |
547
- | `visible` | `boolean` | Controls modal mode menu visibility |
548
- | `onSelect` | `(data, label, index) => void` | Called when user selects an option |
549
- | `onRequestClose` | `() => void` | Called when menu is dismissed without selection |
550
- | `android.material` | `'system' \| 'm3'` | Material Design style preference |
557
+ | Prop | Type | Description |
558
+ | ------------------ | ----------------------------------- | ----------------------------------------------- |
559
+ | `options` | `{ label: string; data: string }[]` | Array of options to display |
560
+ | `selected` | `string \| null` | Currently selected option's `data` value |
561
+ | `disabled` | `boolean` | Disables the menu |
562
+ | `placeholder` | `string` | Placeholder text when no selection |
563
+ | `presentation` | `'modal' \| 'embedded'` | Presentation mode (default: `'modal'`) |
564
+ | `visible` | `boolean` | Controls modal mode menu visibility |
565
+ | `onSelect` | `(data, label, index) => void` | Called when user selects an option |
566
+ | `onRequestClose` | `() => void` | Called when menu is dismissed without selection |
567
+ | `android.material` | `'system' \| 'm3'` | Material Design style preference |
551
568
 
552
569
  ### Modes
553
570
 
@@ -564,39 +581,40 @@ Native segmented control using **UISegmentedControl** on iOS and **MaterialButto
564
581
 
565
582
  ### Props
566
583
 
567
- | Prop | Type | Description |
568
- |------|------|-------------|
569
- | `segments` | `SegmentedControlSegment[]` | Array of segments to display |
570
- | `selectedValue` | `string \| null` | Currently selected segment's `value` |
571
- | `disabled` | `boolean` | Disables the entire control |
572
- | `onSelect` | `(value: string, index: number) => void` | Called when user selects a segment |
584
+ | Prop | Type | Description |
585
+ | --------------- | ---------------------------------------- | ------------------------------------ |
586
+ | `segments` | `SegmentedControlSegment[]` | Array of segments to display |
587
+ | `selectedValue` | `string \| null` | Currently selected segment's `value` |
588
+ | `disabled` | `boolean` | Disables the entire control |
589
+ | `onSelect` | `(value: string, index: number) => void` | Called when user selects a segment |
573
590
 
574
591
  ### SegmentedControlSegment
575
592
 
576
- | Property | Type | Description |
577
- |----------|------|-------------|
578
- | `label` | `string` | Display text for the segment |
579
- | `value` | `string` | Unique value returned in callbacks |
580
- | `disabled` | `boolean` | Disables this specific segment |
581
- | `icon` | `string` | Icon name (SF Symbol on iOS, drawable on Android) |
593
+ | Property | Type | Description |
594
+ | ---------- | --------- | ------------------------------------------------- |
595
+ | `label` | `string` | Display text for the segment |
596
+ | `value` | `string` | Unique value returned in callbacks |
597
+ | `disabled` | `boolean` | Disables this specific segment |
598
+ | `icon` | `string` | Icon name (SF Symbol on iOS, drawable on Android) |
582
599
 
583
600
  ### iOS Props (`ios`)
584
601
 
585
- | Prop | Type | Description |
586
- |------|------|-------------|
587
- | `momentary` | `boolean` | If true, segments don't show selected state |
602
+ | Prop | Type | Description |
603
+ | ---------------------------------- | --------- | --------------------------------------------------- |
604
+ | `momentary` | `boolean` | If true, segments don't show selected state |
588
605
  | `apportionsSegmentWidthsByContent` | `boolean` | If true, segment widths are proportional to content |
589
- | `selectedSegmentTintColor` | `string` | Tint color for selected segment (hex string) |
606
+ | `selectedSegmentTintColor` | `string` | Tint color for selected segment (hex string) |
590
607
 
591
608
  ### Android Props (`android`)
592
609
 
593
- | Prop | Type | Description |
594
- |------|------|-------------|
610
+ | Prop | Type | Description |
611
+ | ------------------- | --------- | -------------------------------------------- |
595
612
  | `selectionRequired` | `boolean` | If true, one segment must always be selected |
596
613
 
597
614
  ### Icon Support
598
615
 
599
616
  Icons work the same as ContextMenu:
617
+
600
618
  - **iOS**: Use SF Symbol names (e.g., `'list.bullet'`, `'square.grid.2x2'`)
601
619
  - **Android**: Use drawable resource names (e.g., `'list_bullet'`, `'grid_view'`)
602
620
 
@@ -610,32 +628,32 @@ Native glass morphism effect using **UIGlassEffect** on iOS 26+. On Android and
610
628
 
611
629
  ### Props
612
630
 
613
- | Prop | Type | Description |
614
- |------|------|-------------|
615
- | `cornerRadius` | `number` | Corner radius for the glass effect (default: `0`) |
616
- | `children` | `ReactNode` | Content to render inside the glass container |
631
+ | Prop | Type | Description |
632
+ | -------------- | ----------- | ------------------------------------------------- |
633
+ | `cornerRadius` | `number` | Corner radius for the glass effect (default: `0`) |
634
+ | `children` | `ReactNode` | Content to render inside the glass container |
617
635
 
618
636
  ### iOS Props (`ios`)
619
637
 
620
- | Prop | Type | Description |
621
- |------|------|-------------|
622
- | `effect` | `'clear' \| 'regular' \| 'none'` | Glass effect intensity (default: `'regular'`) |
623
- | `interactive` | `boolean` | Enable touch interaction feedback (default: `false`) |
624
- | `tintColor` | `string` | Overlay tint color (hex string) |
625
- | `colorScheme` | `'light' \| 'dark' \| 'system'` | Appearance mode (default: `'system'`) |
626
- | `shadowRadius` | `number` | Shadow/glow radius (default: `20`) |
627
- | `isHighlighted` | `boolean` | Manual highlight state control |
638
+ | Prop | Type | Description |
639
+ | --------------- | -------------------------------- | ---------------------------------------------------- |
640
+ | `effect` | `'clear' \| 'regular' \| 'none'` | Glass effect intensity (default: `'regular'`) |
641
+ | `interactive` | `boolean` | Enable touch interaction feedback (default: `false`) |
642
+ | `tintColor` | `string` | Overlay tint color (hex string) |
643
+ | `colorScheme` | `'light' \| 'dark' \| 'system'` | Appearance mode (default: `'system'`) |
644
+ | `shadowRadius` | `number` | Shadow/glow radius (default: `20`) |
645
+ | `isHighlighted` | `boolean` | Manual highlight state control |
628
646
 
629
647
  ### Android Props (`android`)
630
648
 
631
- | Prop | Type | Description |
632
- |------|------|-------------|
649
+ | Prop | Type | Description |
650
+ | ------------------------- | -------- | ---------------------------------------------- |
633
651
  | `fallbackBackgroundColor` | `string` | Background color when glass effect unavailable |
634
652
 
635
653
  ### Constants
636
654
 
637
- | Export | Type | Description |
638
- |--------|------|-------------|
655
+ | Export | Type | Description |
656
+ | ------------------------ | --------- | ------------------------------------ |
639
657
  | `isLiquidGlassSupported` | `boolean` | `true` on iOS 26+, `false` otherwise |
640
658
 
641
659
  ### Effect Modes
@@ -646,13 +664,13 @@ Native glass morphism effect using **UIGlassEffect** on iOS 26+. On Android and
646
664
 
647
665
  ### Platform Behavior
648
666
 
649
- | Platform | iOS 26+ | iOS < 26 | Android |
650
- |----------|---------|----------|---------|
651
- | Glass Effect | Full glass morphism | No effect | No effect |
652
- | Corner Radius | Applied | Applied | Applied |
653
- | Tint Color | Supported | Ignored | Ignored |
654
- | Interactive | Supported | Ignored | Ignored |
655
- | Fallback BG | N/A | Transparent | Configurable |
667
+ | Platform | iOS 26+ | iOS < 26 | Android |
668
+ | ------------- | ------------------- | ----------- | ------------ |
669
+ | Glass Effect | Full glass morphism | No effect | No effect |
670
+ | Corner Radius | Applied | Applied | Applied |
671
+ | Tint Color | Supported | Ignored | Ignored |
672
+ | Interactive | Supported | Ignored | Ignored |
673
+ | Fallback BG | N/A | Transparent | Configurable |
656
674
 
657
675
  ### Usage Tips
658
676
 
@@ -694,11 +712,11 @@ Use [SF Symbols](https://developer.apple.com/sf-symbols/) names. These are built
694
712
 
695
713
  ```tsx
696
714
  // Common SF Symbols
697
- image: 'doc.on.doc' // Copy
698
- image: 'square.and.arrow.up' // Share
699
- image: 'trash' // Delete
700
- image: 'pencil' // Edit
701
- image: 'checkmark.circle' // Checkmark
715
+ image: 'doc.on.doc'; // Copy
716
+ image: 'square.and.arrow.up'; // Share
717
+ image: 'trash'; // Delete
718
+ image: 'pencil'; // Edit
719
+ image: 'checkmark.circle'; // Checkmark
702
720
  ```
703
721
 
704
722
  Browse available symbols using Apple's SF Symbols app or [sfsymbols.com](https://sfsymbols.com).
@@ -709,9 +727,9 @@ Use drawable resource names from your app's `res/drawable` directory. You must a
709
727
 
710
728
  ```tsx
711
729
  // Reference drawable by name (without extension)
712
- image: 'content_copy' // res/drawable/content_copy.xml
713
- image: 'share' // res/drawable/share.xml
714
- image: 'delete' // res/drawable/delete.xml
730
+ image: 'content_copy'; // res/drawable/content_copy.xml
731
+ image: 'share'; // res/drawable/share.xml
732
+ image: 'delete'; // res/drawable/delete.xml
715
733
  ```
716
734
 
717
735
  **Adding drawable resources:**
@@ -772,3 +790,15 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
772
790
  ## License
773
791
 
774
792
  MIT
793
+
794
+ ---
795
+
796
+ ## Author
797
+
798
+ **Andrew Tosh** — Santa Barbara, California
799
+
800
+ Full-stack developer with deep experience across entertainment and defense industries, specializing in simulation, visualization, and cross-platform mobile development. Technical focus areas include React Native, Rust, C++, real-time 3D visualization, and game engine technologies.
801
+
802
+ **Available for contract work** — Always interested in connecting with new clients for mobile development, visualization systems, and related projects. Hit me up at [andrew.tosh@jarxconcepts.com](mailto:andrew.tosh@jarxconcepts.com).
803
+
804
+ [LinkedIn](https://www.linkedin.com/in/atosh/) · [JarX Concepts](https://github.com/JarX-Concepts)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-platform-components",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
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",