react-native-platform-components 0.5.4 → 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 +7 -7
- package/ios/PCDatePickerView.swift +39 -0
- package/lib/module/SelectionMenu.js +6 -6
- 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/src/SelectionMenu.tsx +13 -12
- package/src/sharedTypes.ts +4 -1
package/README.md
CHANGED
|
@@ -125,7 +125,7 @@ export function Example() {
|
|
|
125
125
|
<SelectionMenu
|
|
126
126
|
options={options}
|
|
127
127
|
selected={value}
|
|
128
|
-
|
|
128
|
+
presentation="embedded"
|
|
129
129
|
placeholder="Select fruit"
|
|
130
130
|
onSelect={(data) => setValue(data)}
|
|
131
131
|
android={{ material: 'm3' }}
|
|
@@ -194,7 +194,7 @@ export function Example() {
|
|
|
194
194
|
|
|
195
195
|
## SelectionMenu
|
|
196
196
|
|
|
197
|
-
Native selection menu with **
|
|
197
|
+
Native selection menu with **modal** and **embedded** modes.
|
|
198
198
|
|
|
199
199
|
### Props
|
|
200
200
|
|
|
@@ -204,18 +204,18 @@ Native selection menu with **inline** and **headless** modes.
|
|
|
204
204
|
| `selected` | `string \| null` | Currently selected option's `data` value |
|
|
205
205
|
| `disabled` | `boolean` | Disables the menu |
|
|
206
206
|
| `placeholder` | `string` | Placeholder text when no selection |
|
|
207
|
-
| `
|
|
208
|
-
| `visible` | `boolean` | Controls
|
|
207
|
+
| `presentation` | `'modal' \| 'embedded'` | Presentation mode (default: `'modal'`) |
|
|
208
|
+
| `visible` | `boolean` | Controls modal mode menu visibility |
|
|
209
209
|
| `onSelect` | `(data, label, index) => void` | Called when user selects an option |
|
|
210
210
|
| `onRequestClose` | `() => void` | Called when menu is dismissed without selection |
|
|
211
211
|
| `android.material` | `'system' \| 'm3'` | Material Design style preference |
|
|
212
212
|
|
|
213
213
|
### Modes
|
|
214
214
|
|
|
215
|
-
- **
|
|
216
|
-
- **
|
|
215
|
+
- **Modal mode** (default): Menu visibility controlled by `visible` prop. Use for custom trigger UI.
|
|
216
|
+
- **Embedded mode** (`presentation="embedded"`): Native picker UI rendered inline. Menu managed internally.
|
|
217
217
|
|
|
218
|
-
> **Note:** On iOS,
|
|
218
|
+
> **Note:** On iOS, modal mode uses a custom popover to enable programmatic presentation. For the full native menu experience (system animations, scroll physics), use embedded mode. This is an intentional trade-off: modal gives you control over the trigger UI, embedded gives you the complete system menu behavior.
|
|
219
219
|
|
|
220
220
|
---
|
|
221
221
|
|
|
@@ -120,6 +120,41 @@ public final class PCDatePickerView: UIControl,
|
|
|
120
120
|
|
|
121
121
|
// MARK: - Layout / Sizing
|
|
122
122
|
|
|
123
|
+
private var lastLayoutBounds: CGRect = .zero
|
|
124
|
+
private var needsStyleReset = false
|
|
125
|
+
|
|
126
|
+
public override func layoutSubviews() {
|
|
127
|
+
super.layoutSubviews()
|
|
128
|
+
|
|
129
|
+
// For embedded presentation, manually center the picker after Auto Layout
|
|
130
|
+
// This ensures consistent centering regardless of UIDatePicker's internal state
|
|
131
|
+
if presentation == "embedded" && picker.superview === self && bounds.width > 0 {
|
|
132
|
+
let widthChanged = abs(bounds.width - lastLayoutBounds.width) > 1
|
|
133
|
+
if needsStyleReset || widthChanged {
|
|
134
|
+
if #available(iOS 13.4, *) {
|
|
135
|
+
let currentStyle = picker.preferredDatePickerStyle
|
|
136
|
+
picker.preferredDatePickerStyle = .automatic
|
|
137
|
+
picker.preferredDatePickerStyle = currentStyle
|
|
138
|
+
}
|
|
139
|
+
picker.sizeToFit()
|
|
140
|
+
needsStyleReset = false
|
|
141
|
+
}
|
|
142
|
+
lastLayoutBounds = bounds
|
|
143
|
+
|
|
144
|
+
// After constraints do their thing, manually adjust picker position to center it
|
|
145
|
+
let pickerSize = picker.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
|
|
146
|
+
let xOffset = (bounds.width - pickerSize.width) / 2
|
|
147
|
+
if xOffset > 0 {
|
|
148
|
+
picker.frame = CGRect(
|
|
149
|
+
x: xOffset,
|
|
150
|
+
y: 0,
|
|
151
|
+
width: pickerSize.width,
|
|
152
|
+
height: bounds.height
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
123
158
|
private func invalidateSize() {
|
|
124
159
|
invalidateIntrinsicContentSize()
|
|
125
160
|
setNeedsLayout()
|
|
@@ -192,6 +227,10 @@ public final class PCDatePickerView: UIControl,
|
|
|
192
227
|
picker.removeFromSuperview()
|
|
193
228
|
addSubview(picker)
|
|
194
229
|
|
|
230
|
+
// Mark that we need a style reset on next layout pass
|
|
231
|
+
// This ensures centering is recalculated after Yoga provides correct bounds
|
|
232
|
+
needsStyleReset = true
|
|
233
|
+
|
|
195
234
|
inlineConstraints = [
|
|
196
235
|
picker.topAnchor.constraint(equalTo: topAnchor),
|
|
197
236
|
picker.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
@@ -7,9 +7,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
7
7
|
function normalizeSelectedData(selected) {
|
|
8
8
|
return selected ?? '';
|
|
9
9
|
}
|
|
10
|
-
function normalizeNativeVisible(
|
|
11
|
-
//
|
|
12
|
-
if (
|
|
10
|
+
function normalizeNativeVisible(presentation, visible) {
|
|
11
|
+
// Embedded mode ignores visible; keep it undefined so native isn't spammed.
|
|
12
|
+
if (presentation === 'embedded') return undefined;
|
|
13
13
|
return visible ? 'open' : 'closed';
|
|
14
14
|
}
|
|
15
15
|
export function SelectionMenu(props) {
|
|
@@ -19,7 +19,7 @@ export function SelectionMenu(props) {
|
|
|
19
19
|
selected,
|
|
20
20
|
disabled,
|
|
21
21
|
placeholder,
|
|
22
|
-
|
|
22
|
+
presentation = 'modal',
|
|
23
23
|
visible,
|
|
24
24
|
onSelect,
|
|
25
25
|
onRequestClose,
|
|
@@ -28,7 +28,7 @@ export function SelectionMenu(props) {
|
|
|
28
28
|
...viewProps
|
|
29
29
|
} = props;
|
|
30
30
|
const selectedData = useMemo(() => normalizeSelectedData(selected), [selected]);
|
|
31
|
-
const nativeVisible = useMemo(() => normalizeNativeVisible(
|
|
31
|
+
const nativeVisible = useMemo(() => normalizeNativeVisible(presentation, visible), [presentation, visible]);
|
|
32
32
|
const handleSelect = useCallback(e => {
|
|
33
33
|
const {
|
|
34
34
|
index,
|
|
@@ -54,7 +54,7 @@ export function SelectionMenu(props) {
|
|
|
54
54
|
selectedData: selectedData,
|
|
55
55
|
interactivity: disabled ? 'disabled' : 'enabled',
|
|
56
56
|
placeholder: placeholder,
|
|
57
|
-
anchorMode:
|
|
57
|
+
anchorMode: presentation === 'embedded' ? 'inline' : 'headless',
|
|
58
58
|
visible: nativeVisible,
|
|
59
59
|
onSelect: onSelect ? handleSelect : undefined,
|
|
60
60
|
onRequestClose: onRequestClose ? handleRequestClose : undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useMemo","NativeSelectionMenu","jsx","_jsx","normalizeSelectedData","selected","normalizeNativeVisible","
|
|
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;AAGnD,OAAOC,mBAAmB,MAGnB,gCAAgC;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAuDxC,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,GAAGrB,OAAO,CAC1B,MAAMI,qBAAqB,CAACC,QAAQ,CAAC,EACrC,CAACA,QAAQ,CACX,CAAC;EAED,MAAMiB,aAAa,GAAGtB,OAAO,CAC3B,MAAMM,sBAAsB,CAACC,YAAY,EAAEC,OAAO,CAAC,EACnD,CAACD,YAAY,EAAEC,OAAO,CACxB,CAAC;EAED,MAAMe,YAAY,GAAGxB,WAAW,CAC7ByB,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,GAAG9B,WAAW,CAAC,MAAM;IAC3CkB,cAAc,GAAG,CAAC;EACpB,CAAC,EAAE,CAACA,cAAc,CAAC,CAAC;;EAEpB;EACA,MAAMa,aAAa,GAAG9B,OAAO,CAAC,MAAM;IAClC,IAAI,CAACmB,OAAO,EAAE,OAAOV,SAAS;IAC9B,OAAO;MAAEsB,QAAQ,EAAEZ,OAAO,CAACY;IAAS,CAAC;EACvC,CAAC,EAAE,CAACZ,OAAO,CAAC,CAAC;EAEb,oBACEhB,IAAA,CAACF,mBAAmB;IAClBW,KAAK,EAAEA,KAAM;IACbC,OAAO,EAAEA,OAAQ;IACjBQ,YAAY,EAAEA,YAAa;IAC3BW,aAAa,EAAElB,QAAQ,GAAG,UAAU,GAAG,SAAU;IACjDC,WAAW,EAAEA,WAAY;IACzBkB,UAAU,EAAE1B,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,CACd,CAAC;AAEN","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type ViewProps } from 'react-native';
|
|
3
3
|
import { type SelectionMenuOption } from './SelectionMenuNativeComponent';
|
|
4
|
-
import type { AndroidMaterialMode } from './sharedTypes';
|
|
4
|
+
import type { AndroidMaterialMode, Presentation } from './sharedTypes';
|
|
5
5
|
export interface SelectionMenuProps extends ViewProps {
|
|
6
6
|
/** Options are label + data (payload) */
|
|
7
7
|
options: readonly SelectionMenuOption[];
|
|
@@ -13,12 +13,13 @@ export interface SelectionMenuProps extends ViewProps {
|
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
placeholder?: string;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Presentation mode:
|
|
17
|
+
* - 'modal' (default): Headless mode, controlled by `visible` prop.
|
|
18
|
+
* - 'embedded': Native renders its own inline anchor and manages open/close internally.
|
|
18
19
|
*/
|
|
19
|
-
|
|
20
|
+
presentation?: Presentation;
|
|
20
21
|
/**
|
|
21
|
-
*
|
|
22
|
+
* Modal mode only (presentation === 'modal'):
|
|
22
23
|
* controls whether the native menu UI is presented.
|
|
23
24
|
*/
|
|
24
25
|
visible?: boolean;
|
|
@@ -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,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAA4B,EAC1B,KAAK,mBAAmB,EAEzB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"SelectionMenu.d.ts","sourceRoot":"","sources":["../../../src/SelectionMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAA4B,EAC1B,KAAK,mBAAmB,EAEzB,MAAM,gCAAgC,CAAC;AAExC,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,CA4D3E"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { CodegenTypes } from 'react-native';
|
|
2
|
-
/** Shared
|
|
2
|
+
/** Shared "open/closed" control state. */
|
|
3
3
|
export type Visible = 'open' | 'closed';
|
|
4
|
+
/** Shared presentation mode for pickers/menus. */
|
|
5
|
+
export type Presentation = 'modal' | 'embedded';
|
|
4
6
|
/** Shared Material preference (Android). */
|
|
5
7
|
export type AndroidMaterialMode = 'system' | 'm3';
|
|
6
8
|
/** Common event empty payload type. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTypes.d.ts","sourceRoot":"","sources":["../../../src/sharedTypes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,0CAA0C;AAC1C,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAExC,4CAA4C;AAC5C,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,IAAI,CAAC;AAElD,uCAAuC;AACvC,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AAEtC,oCAAoC;AACpC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"sharedTypes.d.ts","sourceRoot":"","sources":["../../../src/sharedTypes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,0CAA0C;AAC1C,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAExC,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,CAAC;AAEhD,4CAA4C;AAC5C,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,IAAI,CAAC;AAElD,uCAAuC;AACvC,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;AAEtC,oCAAoC;AACpC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-platform-components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
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",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"release": "release-it",
|
|
43
43
|
"test": "jest",
|
|
44
44
|
"upgrade:check": "yarn dlx npm-check-updates",
|
|
45
|
-
"upgrade:apply": "yarn dlx npm-check-updates -u && rm -rf node_modules && rm -rf package-lock.json && yarn install"
|
|
45
|
+
"upgrade:apply": "yarn dlx npm-check-updates -u && rm -rf node_modules && rm -rf package-lock.json && yarn install",
|
|
46
|
+
"generate:gifs": "./scripts/generate-readme-gifs.sh"
|
|
46
47
|
},
|
|
47
48
|
"keywords": [
|
|
48
49
|
"react-native",
|
package/src/SelectionMenu.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import NativeSelectionMenu, {
|
|
|
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(
|
|
@@ -123,7 +124,7 @@ export function SelectionMenu(props: SelectionMenuProps): React.ReactElement {
|
|
|
123
124
|
selectedData={selectedData}
|
|
124
125
|
interactivity={disabled ? 'disabled' : 'enabled'}
|
|
125
126
|
placeholder={placeholder}
|
|
126
|
-
anchorMode={
|
|
127
|
+
anchorMode={presentation === 'embedded' ? 'inline' : 'headless'}
|
|
127
128
|
visible={nativeVisible}
|
|
128
129
|
onSelect={onSelect ? handleSelect : undefined}
|
|
129
130
|
onRequestClose={onRequestClose ? handleRequestClose : undefined}
|
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
|
|