react-native-platform-components 0.5.3 → 0.5.5
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 +13 -8
- package/android/build.gradle +3 -1
- package/android/src/main/java/com/platformcomponents/PCConstants.kt +3 -0
- package/android/src/main/java/com/platformcomponents/PCDatePickerView.kt +53 -1
- package/android/src/main/java/com/platformcomponents/PCDatePickerViewManager.kt +14 -0
- package/android/src/main/java/com/platformcomponents/PCSelectionMenuView.kt +169 -10
- package/android/src/main/java/com/platformcomponents/PCSelectionMenuViewManager.kt +14 -0
- package/android/src/main/jni/CMakeLists.txt +47 -0
- package/android/src/main/jni/OnLoad.cpp +33 -0
- package/ios/PCDatePickerView.swift +58 -2
- package/ios/PCSelectionMenu.mm +42 -0
- package/ios/PCSelectionMenu.swift +17 -0
- package/lib/module/SelectionMenu.js +7 -14
- package/lib/module/SelectionMenu.js.map +1 -1
- package/lib/typescript/src/SelectionMenu.d.ts +6 -5
- package/lib/typescript/src/SelectionMenu.d.ts.map +1 -1
- package/lib/typescript/src/sharedTypes.d.ts +3 -1
- package/lib/typescript/src/sharedTypes.d.ts.map +1 -1
- package/package.json +3 -2
- package/react-native.config.js +13 -0
- package/shared/PCDatePickerComponentDescriptors-custom.h +14 -43
- package/shared/PCDatePickerShadowNode-custom.cpp +35 -0
- package/shared/PCDatePickerShadowNode-custom.h +40 -18
- package/shared/PCDatePickerState-custom.h +53 -1
- package/shared/PCSelectionMenuComponentDescriptors-custom.h +15 -18
- package/shared/PCSelectionMenuShadowNode-custom.cpp +42 -21
- package/shared/PCSelectionMenuShadowNode-custom.h +23 -10
- package/shared/PCSelectionMenuState-custom.h +65 -0
- package/shared/README.md +179 -0
- package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +9 -0
- package/src/SelectionMenu.tsx +15 -24
- package/src/sharedTypes.ts +4 -1
|
@@ -2,31 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
#
|
|
5
|
+
// Only include what we need for the shadow node definition
|
|
6
|
+
// Do NOT include ComponentDescriptors.h here to avoid circular dependency
|
|
7
|
+
#include <react/renderer/components/PlatformComponentsViewSpec/EventEmitters.h>
|
|
8
|
+
#include <react/renderer/components/PlatformComponentsViewSpec/Props.h>
|
|
9
|
+
|
|
10
|
+
#include "PCSelectionMenuState-custom.h"
|
|
8
11
|
|
|
9
12
|
namespace facebook::react {
|
|
10
13
|
|
|
11
14
|
extern const char PCSelectionMenuComponentName[];
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
|
-
* ShadowNode for SelectionMenu.
|
|
17
|
+
* Custom ShadowNode for SelectionMenu that supports Yoga measurement.
|
|
15
18
|
*
|
|
16
19
|
* Key behavior:
|
|
17
|
-
* -
|
|
18
|
-
*
|
|
20
|
+
* - Native side measures the actual picker and updates state with frameSize
|
|
21
|
+
* - measureContent() returns the size from state for proper Yoga layout
|
|
22
|
+
* - Falls back to platform-specific defaults if state hasn't been set yet
|
|
19
23
|
*/
|
|
20
24
|
class MeasuringPCSelectionMenuShadowNode final : public ConcreteViewShadowNode<
|
|
21
25
|
PCSelectionMenuComponentName,
|
|
22
26
|
PCSelectionMenuProps,
|
|
23
27
|
PCSelectionMenuEventEmitter,
|
|
24
|
-
|
|
28
|
+
PCSelectionMenuStateFrameSize> {
|
|
25
29
|
public:
|
|
26
30
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
// Fallback heights used when native hasn't reported measurements yet
|
|
33
|
+
// iOS standard row height
|
|
34
|
+
static constexpr float kFallbackHeightIOS = 44.0f;
|
|
35
|
+
|
|
36
|
+
// Android System Spinner height
|
|
37
|
+
static constexpr float kFallbackHeightAndroid = 56.0f;
|
|
38
|
+
|
|
39
|
+
// Android M3 TextInputLayout with floating label height
|
|
40
|
+
static constexpr float kFallbackHeightAndroidM3 = 72.0f;
|
|
41
|
+
|
|
30
42
|
static ShadowNodeTraits BaseTraits() {
|
|
31
43
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
32
44
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
@@ -36,7 +48,8 @@ class MeasuringPCSelectionMenuShadowNode final : public ConcreteViewShadowNode<
|
|
|
36
48
|
|
|
37
49
|
/**
|
|
38
50
|
* Called by Yoga when it needs the intrinsic size of the component.
|
|
39
|
-
*
|
|
51
|
+
* Returns the size provided by native through state, with fallback to
|
|
52
|
+
* platform-specific defaults if state hasn't been set.
|
|
40
53
|
*/
|
|
41
54
|
Size measureContent(
|
|
42
55
|
const LayoutContext& layoutContext,
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <react/renderer/core/LayoutPrimitives.h>
|
|
4
|
+
#include <memory>
|
|
5
|
+
|
|
6
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
7
|
+
#include <folly/dynamic.h>
|
|
8
|
+
#include <react/renderer/mapbuffer/MapBuffer.h>
|
|
9
|
+
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
|
|
10
|
+
#endif
|
|
11
|
+
|
|
12
|
+
namespace facebook::react {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Custom state for SelectionMenu that holds the measured frame size from native.
|
|
16
|
+
* This allows the native side to measure the actual picker and communicate
|
|
17
|
+
* the size to the shadow node for proper Yoga layout.
|
|
18
|
+
*
|
|
19
|
+
* Note: Does NOT inherit from StateData (which is final). Custom state types
|
|
20
|
+
* are standalone structs that satisfy the ConcreteState template requirements.
|
|
21
|
+
*/
|
|
22
|
+
struct PCSelectionMenuStateFrameSize {
|
|
23
|
+
using Shared = std::shared_ptr<const PCSelectionMenuStateFrameSize>;
|
|
24
|
+
|
|
25
|
+
Size frameSize{}; // {width, height} in points
|
|
26
|
+
|
|
27
|
+
PCSelectionMenuStateFrameSize() = default;
|
|
28
|
+
|
|
29
|
+
explicit PCSelectionMenuStateFrameSize(Size size) : frameSize(size) {}
|
|
30
|
+
|
|
31
|
+
bool operator==(const PCSelectionMenuStateFrameSize& other) const {
|
|
32
|
+
return frameSize.width == other.frameSize.width &&
|
|
33
|
+
frameSize.height == other.frameSize.height;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
bool operator!=(const PCSelectionMenuStateFrameSize& other) const {
|
|
37
|
+
return !(*this == other);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
41
|
+
// Required for Android state serialization
|
|
42
|
+
PCSelectionMenuStateFrameSize(
|
|
43
|
+
const PCSelectionMenuStateFrameSize& previousState,
|
|
44
|
+
folly::dynamic data)
|
|
45
|
+
: frameSize(previousState.frameSize) {
|
|
46
|
+
// Parse frame size from dynamic data if provided
|
|
47
|
+
if (data.isObject()) {
|
|
48
|
+
if (data.count("width") && data.count("height")) {
|
|
49
|
+
frameSize.width = static_cast<Float>(data["width"].asDouble());
|
|
50
|
+
frameSize.height = static_cast<Float>(data["height"].asDouble());
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
folly::dynamic getDynamic() const {
|
|
56
|
+
return folly::dynamic::object("width", frameSize.width)("height", frameSize.height);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
MapBuffer getMapBuffer() const {
|
|
60
|
+
return MapBufferBuilder::EMPTY();
|
|
61
|
+
}
|
|
62
|
+
#endif
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
} // namespace facebook::react
|
package/shared/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Shared C++ Code for Yoga Shadow Node Measurement
|
|
2
|
+
|
|
3
|
+
This directory contains cross-platform C++ code that enables native components to report their measured sizes to React Native's Yoga layout engine. This allows components like `DatePicker` and `SelectionMenu` to have "perfect" sizing based on their actual native content, rather than relying on hardcoded dimensions.
|
|
4
|
+
|
|
5
|
+
## Architecture Overview
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
9
|
+
│ React Native (JS) │
|
|
10
|
+
│ <DatePicker /> <SelectionMenu /> │
|
|
11
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
12
|
+
│
|
|
13
|
+
▼
|
|
14
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
15
|
+
│ Yoga Layout Engine (C++) │
|
|
16
|
+
│ │
|
|
17
|
+
│ Calls measureContent() on shadow nodes to determine intrinsic size │
|
|
18
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
19
|
+
│
|
|
20
|
+
▼
|
|
21
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
22
|
+
│ Custom Shadow Nodes (this directory) │
|
|
23
|
+
│ │
|
|
24
|
+
│ MeasuringPCDatePickerShadowNode │
|
|
25
|
+
│ MeasuringPCSelectionMenuShadowNode │
|
|
26
|
+
│ │
|
|
27
|
+
│ - Marked as LeafYogaNode + MeasurableYogaNode │
|
|
28
|
+
│ - Override measureContent() to return size from state │
|
|
29
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
30
|
+
│
|
|
31
|
+
▼
|
|
32
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
33
|
+
│ Custom State (this directory) │
|
|
34
|
+
│ │
|
|
35
|
+
│ PCDatePickerStateFrameSize { Size frameSize } │
|
|
36
|
+
│ PCSelectionMenuStateFrameSize { Size frameSize } │
|
|
37
|
+
│ │
|
|
38
|
+
│ - Holds measured dimensions from native │
|
|
39
|
+
│ - Supports serialization for Android (folly::dynamic) │
|
|
40
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
41
|
+
▲
|
|
42
|
+
│
|
|
43
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
44
|
+
│ Native Views (iOS/Android) │
|
|
45
|
+
│ │
|
|
46
|
+
│ iOS: PCDatePickerView, PCSelectionMenuView │
|
|
47
|
+
│ Android: PCDatePickerView, PCSelectionMenuView │
|
|
48
|
+
│ │
|
|
49
|
+
│ - Measure actual native content │
|
|
50
|
+
│ - Call state->updateState() with measured frameSize │
|
|
51
|
+
│ - Triggers Yoga re-layout with correct dimensions │
|
|
52
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## How It Works
|
|
56
|
+
|
|
57
|
+
### 1. Shadow Node Traits
|
|
58
|
+
|
|
59
|
+
Shadow nodes are marked with two critical traits:
|
|
60
|
+
|
|
61
|
+
```cpp
|
|
62
|
+
static ShadowNodeTraits BaseTraits() {
|
|
63
|
+
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
64
|
+
traits.set(ShadowNodeTraits::Trait::LeafYogaNode); // No Yoga children
|
|
65
|
+
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode); // Has measureContent()
|
|
66
|
+
return traits;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- **LeafYogaNode**: Tells Yoga this node has no children to layout
|
|
71
|
+
- **MeasurableYogaNode**: Tells Yoga to call `measureContent()` for intrinsic sizing
|
|
72
|
+
|
|
73
|
+
### 2. Measurement Flow
|
|
74
|
+
|
|
75
|
+
```cpp
|
|
76
|
+
Size measureContent(
|
|
77
|
+
const LayoutContext& layoutContext,
|
|
78
|
+
const LayoutConstraints& layoutConstraints) const override {
|
|
79
|
+
|
|
80
|
+
// Get the measured size from native (via state)
|
|
81
|
+
const auto& stateData = this->getStateData();
|
|
82
|
+
Float measuredW = stateData.frameSize.width;
|
|
83
|
+
Float measuredH = stateData.frameSize.height;
|
|
84
|
+
|
|
85
|
+
// Apply layout constraints and return
|
|
86
|
+
return layoutConstraints.clamp(Size{measuredW, measuredH});
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 3. Native → Shadow Node Communication (State)
|
|
91
|
+
|
|
92
|
+
Native views measure their content and update the shadow node's state:
|
|
93
|
+
|
|
94
|
+
**iOS (Objective-C++):**
|
|
95
|
+
```objc
|
|
96
|
+
- (void)updateMeasurements {
|
|
97
|
+
CGSize size = [_nativeView sizeForLayoutWithConstrainedTo:...];
|
|
98
|
+
|
|
99
|
+
PCDatePickerStateFrameSize next;
|
|
100
|
+
next.frameSize = {(Float)size.width, (Float)size.height};
|
|
101
|
+
_state->updateState(std::move(next));
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Android (Kotlin + JNI):**
|
|
106
|
+
```kotlin
|
|
107
|
+
private fun updateMeasurements(width: Float, height: Float) {
|
|
108
|
+
updateState(width, height) // JNI call to C++
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 4. State Serialization (Android)
|
|
113
|
+
|
|
114
|
+
Android requires state to be serializable via `folly::dynamic`:
|
|
115
|
+
|
|
116
|
+
```cpp
|
|
117
|
+
struct PCDatePickerStateFrameSize {
|
|
118
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
119
|
+
// Constructor from dynamic data
|
|
120
|
+
PCDatePickerStateFrameSize(
|
|
121
|
+
const PCDatePickerStateFrameSize& previousState,
|
|
122
|
+
folly::dynamic data) {
|
|
123
|
+
if (data.isObject() && data.count("width") && data.count("height")) {
|
|
124
|
+
frameSize.width = static_cast<Float>(data["width"].asDouble());
|
|
125
|
+
frameSize.height = static_cast<Float>(data["height"].asDouble());
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
folly::dynamic getDynamic() const {
|
|
130
|
+
return folly::dynamic::object("width", frameSize.width)("height", frameSize.height);
|
|
131
|
+
}
|
|
132
|
+
#endif
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## File Structure
|
|
137
|
+
|
|
138
|
+
| File | Purpose |
|
|
139
|
+
|------|---------|
|
|
140
|
+
| `PC*ShadowNode-custom.h` | Shadow node class declaration with `measureContent()` |
|
|
141
|
+
| `PC*ShadowNode-custom.cpp` | `measureContent()` implementation |
|
|
142
|
+
| `PC*State-custom.h` | State struct holding `frameSize` from native |
|
|
143
|
+
| `PC*ComponentDescriptors-custom.h` | Type alias for component descriptor using custom shadow node |
|
|
144
|
+
|
|
145
|
+
## Fallback Behavior
|
|
146
|
+
|
|
147
|
+
When native hasn't yet reported measurements (state is empty), the shadow nodes use platform-specific fallback heights:
|
|
148
|
+
|
|
149
|
+
```cpp
|
|
150
|
+
// SelectionMenu fallbacks
|
|
151
|
+
static constexpr float kFallbackHeightIOS = 44.0f; // iOS standard row
|
|
152
|
+
static constexpr float kFallbackHeightAndroid = 56.0f; // Android Spinner
|
|
153
|
+
static constexpr float kFallbackHeightAndroidM3 = 72.0f; // Android M3 TextInputLayout
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
This prevents layout jumps on initial render before native measurement completes.
|
|
157
|
+
|
|
158
|
+
## Integration Points
|
|
159
|
+
|
|
160
|
+
### iOS
|
|
161
|
+
|
|
162
|
+
- `ios/PCDatePicker.mm` - Calls `updateMeasurements` when props change
|
|
163
|
+
- `ios/PCSelectionMenu.mm` - Calls `updateMeasurements` when props change
|
|
164
|
+
|
|
165
|
+
### Android
|
|
166
|
+
|
|
167
|
+
- `android/.../PCDatePickerView.kt` - Calls JNI `updateState()` after measure
|
|
168
|
+
- `android/.../PCSelectionMenuView.kt` - Calls JNI `updateState()` after measure
|
|
169
|
+
- `android/src/main/jni/OnLoad.cpp` - JNI bridge for state updates
|
|
170
|
+
|
|
171
|
+
## Common Pitfalls
|
|
172
|
+
|
|
173
|
+
1. **Circular includes**: Shadow node headers should NOT include ComponentDescriptors.h. Use forward declarations instead.
|
|
174
|
+
|
|
175
|
+
2. **State timing**: Native measurement may happen after initial Yoga layout. Always provide sensible fallback values.
|
|
176
|
+
|
|
177
|
+
3. **Width constraints**: When width isn't measured (0), use `layoutConstraints.maximumSize.width` as the width.
|
|
178
|
+
|
|
179
|
+
4. **Android serialization**: The `RN_SERIALIZABLE_STATE` macro gates Android-specific serialization code.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
// Include the codegen-generated component descriptors using include_next
|
|
4
|
+
// This allows us to shadow the header while still including the original
|
|
5
|
+
#include_next <react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h>
|
|
6
|
+
|
|
7
|
+
// Include our custom component descriptors which use measuring shadow nodes
|
|
8
|
+
#include "PCSelectionMenuComponentDescriptors-custom.h"
|
|
9
|
+
#include "PCDatePickerComponentDescriptors-custom.h"
|
package/src/SelectionMenu.tsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// SelectionMenu.tsx
|
|
2
2
|
import React, { useCallback, useMemo } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { type ViewProps } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import NativeSelectionMenu, {
|
|
6
6
|
type SelectionMenuOption,
|
|
7
7
|
type SelectionMenuSelectEvent,
|
|
8
8
|
} from './SelectionMenuNativeComponent';
|
|
9
9
|
|
|
10
|
-
import type { AndroidMaterialMode } from './sharedTypes';
|
|
10
|
+
import type { AndroidMaterialMode, Presentation } from './sharedTypes';
|
|
11
11
|
|
|
12
12
|
export interface SelectionMenuProps extends ViewProps {
|
|
13
13
|
/** Options are label + data (payload) */
|
|
@@ -23,13 +23,14 @@ export interface SelectionMenuProps extends ViewProps {
|
|
|
23
23
|
placeholder?: string;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* Presentation mode:
|
|
27
|
+
* - 'modal' (default): Headless mode, controlled by `visible` prop.
|
|
28
|
+
* - 'embedded': Native renders its own inline anchor and manages open/close internally.
|
|
28
29
|
*/
|
|
29
|
-
|
|
30
|
+
presentation?: Presentation;
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
|
-
*
|
|
33
|
+
* Modal mode only (presentation === 'modal'):
|
|
33
34
|
* controls whether the native menu UI is presented.
|
|
34
35
|
*/
|
|
35
36
|
visible?: boolean;
|
|
@@ -64,11 +65,11 @@ function normalizeSelectedData(selected: string | null): string {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
function normalizeNativeVisible(
|
|
67
|
-
|
|
68
|
+
presentation: Presentation | undefined,
|
|
68
69
|
visible: boolean | undefined
|
|
69
70
|
): 'open' | 'closed' | undefined {
|
|
70
|
-
//
|
|
71
|
-
if (
|
|
71
|
+
// Embedded mode ignores visible; keep it undefined so native isn't spammed.
|
|
72
|
+
if (presentation === 'embedded') return undefined;
|
|
72
73
|
return visible ? 'open' : 'closed';
|
|
73
74
|
}
|
|
74
75
|
|
|
@@ -79,7 +80,7 @@ export function SelectionMenu(props: SelectionMenuProps): React.ReactElement {
|
|
|
79
80
|
selected,
|
|
80
81
|
disabled,
|
|
81
82
|
placeholder,
|
|
82
|
-
|
|
83
|
+
presentation = 'modal',
|
|
83
84
|
visible,
|
|
84
85
|
onSelect,
|
|
85
86
|
onRequestClose,
|
|
@@ -94,8 +95,8 @@ export function SelectionMenu(props: SelectionMenuProps): React.ReactElement {
|
|
|
94
95
|
);
|
|
95
96
|
|
|
96
97
|
const nativeVisible = useMemo(
|
|
97
|
-
() => normalizeNativeVisible(
|
|
98
|
-
[
|
|
98
|
+
() => normalizeNativeVisible(presentation, visible),
|
|
99
|
+
[presentation, visible]
|
|
99
100
|
);
|
|
100
101
|
|
|
101
102
|
const handleSelect = useCallback(
|
|
@@ -116,20 +117,14 @@ export function SelectionMenu(props: SelectionMenuProps): React.ReactElement {
|
|
|
116
117
|
return { material: android.material };
|
|
117
118
|
}, [android]);
|
|
118
119
|
|
|
119
|
-
const isAndroidM3Inline =
|
|
120
|
-
android?.material &&
|
|
121
|
-
inlineMode &&
|
|
122
|
-
android.material === 'm3' &&
|
|
123
|
-
Platform.OS === 'android';
|
|
124
|
-
|
|
125
120
|
return (
|
|
126
121
|
<NativeSelectionMenu
|
|
127
|
-
style={
|
|
122
|
+
style={style}
|
|
128
123
|
options={options}
|
|
129
124
|
selectedData={selectedData}
|
|
130
125
|
interactivity={disabled ? 'disabled' : 'enabled'}
|
|
131
126
|
placeholder={placeholder}
|
|
132
|
-
anchorMode={
|
|
127
|
+
anchorMode={presentation === 'embedded' ? 'inline' : 'headless'}
|
|
133
128
|
visible={nativeVisible}
|
|
134
129
|
onSelect={onSelect ? handleSelect : undefined}
|
|
135
130
|
onRequestClose={onRequestClose ? handleRequestClose : undefined}
|
|
@@ -139,7 +134,3 @@ export function SelectionMenu(props: SelectionMenuProps): React.ReactElement {
|
|
|
139
134
|
/>
|
|
140
135
|
);
|
|
141
136
|
}
|
|
142
|
-
|
|
143
|
-
const styles = StyleSheet.create({
|
|
144
|
-
androidInline: { minHeight: 60 },
|
|
145
|
-
});
|
package/src/sharedTypes.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// SharedTypes.ts
|
|
2
2
|
import type { CodegenTypes } from 'react-native';
|
|
3
3
|
|
|
4
|
-
/** Shared
|
|
4
|
+
/** Shared "open/closed" control state. */
|
|
5
5
|
export type Visible = 'open' | 'closed';
|
|
6
6
|
|
|
7
|
+
/** Shared presentation mode for pickers/menus. */
|
|
8
|
+
export type Presentation = 'modal' | 'embedded';
|
|
9
|
+
|
|
7
10
|
/** Shared Material preference (Android). */
|
|
8
11
|
export type AndroidMaterialMode = 'system' | 'm3';
|
|
9
12
|
|