react-native-platform-components 1.6.0 → 1.7.0

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 (139) hide show
  1. package/README.md +19 -18
  2. package/android/src/main/java/com/platformcomponents/PCActionSheetView.kt +309 -0
  3. package/android/src/main/java/com/platformcomponents/PCActionSheetViewManager.kt +131 -0
  4. package/android/src/main/java/com/platformcomponents/PCButtonGroupView.kt +5 -1
  5. package/android/src/main/java/com/platformcomponents/PCButtonView.kt +5 -1
  6. package/android/src/main/java/com/platformcomponents/PCContextMenuView.kt +82 -27
  7. package/android/src/main/java/com/platformcomponents/PCContextMenuViewManager.kt +12 -13
  8. package/android/src/main/java/com/platformcomponents/PCMenuSupport.kt +66 -2
  9. package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +1 -0
  10. package/android/src/main/res/values/ids.xml +2 -0
  11. package/ios/PCActionSheet.h +12 -0
  12. package/ios/PCActionSheet.mm +160 -0
  13. package/ios/PCActionSheetView.swift +280 -0
  14. package/ios/PCContextMenu.mm +22 -1
  15. package/ios/PCContextMenu.swift +218 -15
  16. package/ios/PCMenuItems.h +2 -1
  17. package/ios/PCMenuSupport.swift +22 -3
  18. package/lib/commonjs/ActionSheet.js +85 -0
  19. package/lib/commonjs/ActionSheet.js.map +1 -0
  20. package/lib/commonjs/ActionSheetNativeComponent.ts +94 -0
  21. package/lib/commonjs/ButtonGroupNativeComponent.ts +2 -0
  22. package/lib/commonjs/ButtonNativeComponent.ts +2 -0
  23. package/lib/commonjs/ContextMenu.js +50 -4
  24. package/lib/commonjs/ContextMenu.js.map +1 -1
  25. package/lib/commonjs/ContextMenuNativeComponent.ts +29 -8
  26. package/lib/commonjs/index.js +11 -0
  27. package/lib/commonjs/index.js.map +1 -1
  28. package/lib/commonjs/index.web.js +7 -0
  29. package/lib/commonjs/index.web.js.map +1 -1
  30. package/lib/commonjs/jest.js +92 -5
  31. package/lib/commonjs/jest.js.map +1 -1
  32. package/lib/commonjs/menuItems.js +2 -1
  33. package/lib/commonjs/menuItems.js.map +1 -1
  34. package/lib/commonjs/selectionIdentifiers.js.map +1 -1
  35. package/lib/commonjs/web/ActionSheet.js +131 -0
  36. package/lib/commonjs/web/ActionSheet.js.map +1 -0
  37. package/lib/commonjs/web/components.js +3 -1
  38. package/lib/commonjs/web/components.js.map +1 -1
  39. package/lib/commonjs/web/containers.js +1 -0
  40. package/lib/commonjs/web/containers.js.map +1 -1
  41. package/lib/module/ActionSheet.js +78 -0
  42. package/lib/module/ActionSheet.js.map +1 -0
  43. package/lib/module/ActionSheetNativeComponent.ts +94 -0
  44. package/lib/module/ButtonGroupNativeComponent.ts +2 -0
  45. package/lib/module/ButtonNativeComponent.ts +2 -0
  46. package/lib/module/ContextMenu.js +51 -4
  47. package/lib/module/ContextMenu.js.map +1 -1
  48. package/lib/module/ContextMenuNativeComponent.ts +29 -8
  49. package/lib/module/index.js +1 -0
  50. package/lib/module/index.js.map +1 -1
  51. package/lib/module/index.web.js +1 -1
  52. package/lib/module/index.web.js.map +1 -1
  53. package/lib/module/jest.js +90 -5
  54. package/lib/module/jest.js.map +1 -1
  55. package/lib/module/menuItems.js +2 -1
  56. package/lib/module/menuItems.js.map +1 -1
  57. package/lib/module/selectionIdentifiers.js.map +1 -1
  58. package/lib/module/web/ActionSheet.js +126 -0
  59. package/lib/module/web/ActionSheet.js.map +1 -0
  60. package/lib/module/web/components.js +2 -0
  61. package/lib/module/web/components.js.map +1 -1
  62. package/lib/module/web/containers.js +1 -0
  63. package/lib/module/web/containers.js.map +1 -1
  64. package/lib/typescript/commonjs/docs/sidebars.d.ts.map +1 -1
  65. package/lib/typescript/commonjs/src/ActionSheet.d.ts +98 -0
  66. package/lib/typescript/commonjs/src/ActionSheet.d.ts.map +1 -0
  67. package/lib/typescript/commonjs/src/ActionSheetNativeComponent.d.ts +78 -0
  68. package/lib/typescript/commonjs/src/ActionSheetNativeComponent.d.ts.map +1 -0
  69. package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts +2 -0
  70. package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts.map +1 -1
  71. package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts +2 -0
  72. package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts.map +1 -1
  73. package/lib/typescript/commonjs/src/ContextMenu.d.ts +22 -6
  74. package/lib/typescript/commonjs/src/ContextMenu.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts +20 -7
  76. package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts.map +1 -1
  77. package/lib/typescript/commonjs/src/index.d.ts +1 -0
  78. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/src/index.web.d.ts +2 -1
  80. package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
  81. package/lib/typescript/commonjs/src/jest.d.ts +17 -3
  82. package/lib/typescript/commonjs/src/jest.d.ts.map +1 -1
  83. package/lib/typescript/commonjs/src/menuItems.d.ts +12 -0
  84. package/lib/typescript/commonjs/src/menuItems.d.ts.map +1 -1
  85. package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts +1 -1
  86. package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/src/web/ActionSheet.d.ts +11 -0
  88. package/lib/typescript/commonjs/src/web/ActionSheet.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/src/web/components.d.ts +1 -0
  90. package/lib/typescript/commonjs/src/web/components.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/src/web/containers.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/src/webComponents.d.ts +2 -0
  93. package/lib/typescript/commonjs/src/webComponents.d.ts.map +1 -1
  94. package/lib/typescript/module/docs/sidebars.d.ts.map +1 -1
  95. package/lib/typescript/module/src/ActionSheet.d.ts +98 -0
  96. package/lib/typescript/module/src/ActionSheet.d.ts.map +1 -0
  97. package/lib/typescript/module/src/ActionSheetNativeComponent.d.ts +78 -0
  98. package/lib/typescript/module/src/ActionSheetNativeComponent.d.ts.map +1 -0
  99. package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts +2 -0
  100. package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts.map +1 -1
  101. package/lib/typescript/module/src/ButtonNativeComponent.d.ts +2 -0
  102. package/lib/typescript/module/src/ButtonNativeComponent.d.ts.map +1 -1
  103. package/lib/typescript/module/src/ContextMenu.d.ts +22 -6
  104. package/lib/typescript/module/src/ContextMenu.d.ts.map +1 -1
  105. package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts +20 -7
  106. package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts.map +1 -1
  107. package/lib/typescript/module/src/index.d.ts +1 -0
  108. package/lib/typescript/module/src/index.d.ts.map +1 -1
  109. package/lib/typescript/module/src/index.web.d.ts +2 -1
  110. package/lib/typescript/module/src/index.web.d.ts.map +1 -1
  111. package/lib/typescript/module/src/jest.d.ts +17 -3
  112. package/lib/typescript/module/src/jest.d.ts.map +1 -1
  113. package/lib/typescript/module/src/menuItems.d.ts +12 -0
  114. package/lib/typescript/module/src/menuItems.d.ts.map +1 -1
  115. package/lib/typescript/module/src/selectionIdentifiers.d.ts +1 -1
  116. package/lib/typescript/module/src/selectionIdentifiers.d.ts.map +1 -1
  117. package/lib/typescript/module/src/web/ActionSheet.d.ts +11 -0
  118. package/lib/typescript/module/src/web/ActionSheet.d.ts.map +1 -0
  119. package/lib/typescript/module/src/web/components.d.ts +1 -0
  120. package/lib/typescript/module/src/web/components.d.ts.map +1 -1
  121. package/lib/typescript/module/src/web/containers.d.ts.map +1 -1
  122. package/lib/typescript/module/src/webComponents.d.ts +2 -0
  123. package/lib/typescript/module/src/webComponents.d.ts.map +1 -1
  124. package/package.json +9 -2
  125. package/src/ActionSheet.tsx +193 -0
  126. package/src/ActionSheetNativeComponent.ts +94 -0
  127. package/src/ButtonGroupNativeComponent.ts +2 -0
  128. package/src/ButtonNativeComponent.ts +2 -0
  129. package/src/ContextMenu.tsx +71 -12
  130. package/src/ContextMenuNativeComponent.ts +29 -8
  131. package/src/index.tsx +1 -0
  132. package/src/index.web.tsx +2 -0
  133. package/src/jest.tsx +108 -4
  134. package/src/menuItems.ts +13 -0
  135. package/src/selectionIdentifiers.ts +1 -1
  136. package/src/web/ActionSheet.tsx +130 -0
  137. package/src/web/components.tsx +5 -0
  138. package/src/web/containers.tsx +1 -0
  139. package/src/webComponents.ts +2 -0
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { ActionSheetProps } from './ActionSheet.js';
2
3
  import type { ButtonProps } from './Button.js';
3
4
  import type { ButtonGroupProps } from './ButtonGroup.js';
4
5
  import type { ContextMenuProps } from './ContextMenu.js';
@@ -18,6 +19,7 @@ import { resolveIcon } from './icons.js';
18
19
  export type * from './DatePicker.js';
19
20
  export type * from './SelectionMenu.js';
20
21
  export type * from './ContextMenu.js';
22
+ export type * from './ActionSheet.js';
21
23
  export type * from './Button.js';
22
24
  export type * from './ButtonGroup.js';
23
25
  export type * from './SplitButton.js';
@@ -117,11 +119,23 @@ export declare const isDateRangePickerSupported: boolean;
117
119
  */
118
120
  export declare function SelectionMenu(props: SelectionMenuProps): React.ReactElement;
119
121
  /**
120
- * Its children in a view carrying `testID`. The menu itself isn't rendered;
121
- * `fireEvent(menu, 'pressAction', id, title)`, `'menuOpen'`, `'menuClose'`
122
- * and `'previewPress'` reach the callbacks.
122
+ * Its children in a view carrying `testID`. While `visible` (or the
123
+ * deprecated `android.visible`) is true, each action follows them as a
124
+ * `Pressable` with the `menuitem` role and the action's `testID` (else
125
+ * `${testID}-${id}`) that calls `onPressAction(id, title)`; submenus and
126
+ * sections list their actions. `fireEvent(menu, 'pressAction', id, title)`,
127
+ * `'menuOpen'`, `'menuClose'` and `'previewPress'` reach the callbacks.
123
128
  */
124
129
  export declare function ContextMenu(props: ContextMenuProps): React.ReactElement;
130
+ /**
131
+ * Its children in a view carrying `testID`. While `visible`, the title and
132
+ * message show as `Text`, and each shown action is a `Pressable` with its
133
+ * `testID` (else `${testID}-${id}`) that calls `onSelect(id)`; a disabled
134
+ * one ignores presses. A cancel `Pressable` with `cancelTestID` (else
135
+ * `${testID}-cancel`) calls `onCancel`. `fireEvent(sheet, 'select', id)` and
136
+ * `fireEvent(sheet, 'cancel')` also work.
137
+ */
138
+ export declare function ActionSheet(props: ActionSheetProps): React.ReactElement;
125
139
  /** A view with the toolbar's children. */
126
140
  export declare function FloatingToolbar(props: FloatingToolbarProps): React.ReactElement;
127
141
  /** A view with its children; a `Pressable` when `onPress` is set. */
@@ -1 +1 @@
1
- {"version":3,"file":"jest.d.ts","sourceRoot":"","sources":["../../../../src/jest.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jest.d.ts","sourceRoot":"","sources":["../../../../src/jest.tsx"],"names":[],"mappings":"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"}
@@ -60,6 +60,16 @@ export interface ContextMenuAction {
60
60
  * - Android: a menu group with group dividers; the title is not shown.
61
61
  */
62
62
  displayInline?: boolean;
63
+ /**
64
+ * Test identifier of the action's menu row, so UI tests (Detox `by.id`)
65
+ * find it without its title. A submenu's row takes one too; an inline
66
+ * section has no row of its own.
67
+ *
68
+ * - iOS: the `accessibilityIdentifier` of the `UIAction` / `UIMenu`.
69
+ * - Android 10+: the tag of the popup row view, which Detox and Espresso
70
+ * match `by.id` against. Not a resource-id.
71
+ */
72
+ testID?: string;
63
73
  }
64
74
  /**
65
75
  * One menu item as native receives it. Every field is set; empty strings
@@ -89,6 +99,8 @@ export type NativeMenuItem = {
89
99
  state: string;
90
100
  /** The action's own haptics; '' = the component's */
91
101
  haptics: string;
102
+ /** Test identifier of the menu row; '' = none */
103
+ testID: string;
92
104
  };
93
105
  /**
94
106
  * Flattens an action tree into the list native expects, depth first: a
@@ -1 +1 @@
1
- {"version":3,"file":"menuItems.d.ts","sourceRoot":"","sources":["../../../../src/menuItems.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAW,CAAC;AACzC,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,YAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC,sBAAsB;IACtB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1C;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GACpC,cAAc,EAAE,CAsClB"}
1
+ {"version":3,"file":"menuItems.d.ts","sourceRoot":"","sources":["../../../../src/menuItems.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAW,CAAC;AACzC,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,YAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC,sBAAsB;IACtB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1C;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GACpC,cAAc,EAAE,CAuClB"}
@@ -1,3 +1,3 @@
1
1
  /** Diagnose identifiers reserved by the native selection protocol. */
2
- export declare function warnSelectionIdentifiers(component: 'SelectionMenu' | 'SegmentedControl', values: readonly string[]): void;
2
+ export declare function warnSelectionIdentifiers(component: 'SelectionMenu' | 'SegmentedControl' | 'ActionSheet', values: readonly string[]): void;
3
3
  //# sourceMappingURL=selectionIdentifiers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selectionIdentifiers.d.ts","sourceRoot":"","sources":["../../../../src/selectionIdentifiers.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,eAAe,GAAG,kBAAkB,EAC/C,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,IAAI,CAYN"}
1
+ {"version":3,"file":"selectionIdentifiers.d.ts","sourceRoot":"","sources":["../../../../src/selectionIdentifiers.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,eAAe,GAAG,kBAAkB,GAAG,aAAa,EAC/D,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,IAAI,CAYN"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import type { ActionSheetProps } from '../ActionSheet.js';
3
+ /**
4
+ * Renders its children; while `visible`, the title, message and actions open
5
+ * in a `<dialog>` with a cancel button below them. Picking an action calls
6
+ * `onSelect`; the cancel button, Escape and a click outside call `onCancel`.
7
+ * Icons draw only for image sources (`{ type: 'image' }`); each button
8
+ * carries its action's `testID` as `data-testid`.
9
+ */
10
+ export declare function ActionSheet(props: ActionSheetProps): React.ReactElement;
11
+ //# sourceMappingURL=ActionSheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionSheet.d.ts","sourceRoot":"","sources":["../../../../../src/web/ActionSheet.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAgB,CAAC;AAOvD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CA+GvE"}
@@ -1,4 +1,5 @@
1
1
  import type { WebComponents } from '../webComponents.js';
2
+ export declare const ActionSheet: WebComponents['ActionSheet'];
2
3
  export declare const Button: WebComponents['Button'];
3
4
  export declare const ButtonGroup: WebComponents['ButtonGroup'];
4
5
  export declare const SplitButton: WebComponents['SplitButton'];
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../src/web/components.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAkB,CAAC;AAoBtD,eAAO,MAAM,MAAM,EAAE,aAAa,CAAC,QAAQ,CAG1C,CAAC;AACF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,YAAY,CAGlD,CAAC;AACF,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,iBAAiB,CACA,CAAC;AAC9D,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,sBAAsB,CACA,CAAC;AACxE,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,gBAAgB,CAG1D,CAAC;AACF,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CACA,CAAC;AAChE,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,eAAe,CAGxD,CAAC;AACF,eAAO,MAAM,MAAM,EAAE,aAAa,CAAC,QAAQ,CAG1C,CAAC;AACF,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,WAAW,CAGhD,CAAC;AACF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,iBAAiB,CACA,CAAC;AAC9D,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,sBAAsB,CACA,CAAC"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../src/web/components.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAkB,CAAC;AAqBtD,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,MAAM,EAAE,aAAa,CAAC,QAAQ,CAG1C,CAAC;AACF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,YAAY,CAGlD,CAAC;AACF,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,iBAAiB,CACA,CAAC;AAC9D,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,sBAAsB,CACA,CAAC;AACxE,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,gBAAgB,CAG1D,CAAC;AACF,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CACA,CAAC;AAChE,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,eAAe,CAGxD,CAAC;AACF,eAAO,MAAM,MAAM,EAAE,aAAa,CAAC,QAAQ,CAG1C,CAAC;AACF,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,WAAW,CAGhD,CAAC;AACF,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,iBAAiB,CACA,CAAC;AAC9D,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,CAGpD,CAAC;AACF,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,sBAAsB,CACA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"containers.d.ts","sourceRoot":"","sources":["../../../../../src/web/containers.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAAyB,CAAC;AAGzE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAuBvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,oBAAoB,GAC1B,KAAK,CAAC,YAAY,CAkCpB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CA8BvE;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,yBAAyB,GAC/B,KAAK,CAAC,YAAY,CAGpB;AAED,eAAO,MAAM,sBAAsB,QAAQ,CAAC"}
1
+ {"version":3,"file":"containers.d.ts","sourceRoot":"","sources":["../../../../../src/web/containers.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAAyB,CAAC;AAGzE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAwBvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,oBAAoB,GAC1B,KAAK,CAAC,YAAY,CAkCpB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CA8BvE;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,yBAAyB,GAC/B,KAAK,CAAC,YAAY,CAGpB;AAED,eAAO,MAAM,sBAAsB,QAAQ,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { ComponentType, ReactNode, RefAttributes } from 'react';
2
+ import type { ActionSheetProps } from './ActionSheet.js';
2
3
  import type { ButtonProps } from './Button.js';
3
4
  import type { ButtonGroupProps } from './ButtonGroup.js';
4
5
  import type { SplitButtonProps } from './SplitButton.js';
@@ -15,6 +16,7 @@ import type { TabBarProps } from './TabBar.js';
15
16
  import type { TextFieldProps, TextFieldRef } from './TextField.js';
16
17
  /** Public contracts accepted by consumer-supplied web components. */
17
18
  export interface WebComponentProps {
19
+ ActionSheet: ActionSheetProps;
18
20
  Button: ButtonProps;
19
21
  ButtonGroup: ButtonGroupProps;
20
22
  SplitButton: SplitButtonProps;
@@ -1 +1 @@
1
- {"version":3,"file":"webComponents.d.ts","sourceRoot":"","sources":["../../../../src/webComponents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,iBAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAa,CAAC;AAEhE,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,oBAAoB,CAAC;IACtC,oBAAoB,EAAE,yBAAyB,CAAC;IAChD,eAAe,EAAE,oBAAoB,CAAC;IACtC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,oBAAoB,EAAE,yBAAyB,CAAC;IAChD,cAAc,EAAE,mBAAmB,CAAC;IACpC,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,aAAa,EAAE,kBAAkB,CAAC;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,cAAc,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;CACzD;AAED,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG;KACzB,IAAI,IAAI,MAAM,iBAAiB,GAAG,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;CAC1E,CAAC;AAEF,MAAM,WAAW,+BAA+B;IAC9C,kEAAkE;IAClE,GAAG,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
1
+ {"version":3,"file":"webComponents.d.ts","sourceRoot":"","sources":["../../../../src/webComponents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,iBAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAe,CAAC;AACtD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAa,CAAC;AAEhE,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,oBAAoB,CAAC;IACtC,oBAAoB,EAAE,yBAAyB,CAAC;IAChD,eAAe,EAAE,oBAAoB,CAAC;IACtC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,oBAAoB,EAAE,yBAAyB,CAAC;IAChD,cAAc,EAAE,mBAAmB,CAAC;IACpC,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,aAAa,EAAE,kBAAkB,CAAC;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,cAAc,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;CACzD;AAED,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG;KACzB,IAAI,IAAI,MAAM,iBAAiB,GAAG,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;CAC1E,CAAC;AAEF,MAAM,WAAW,+BAA+B;IAC9C,kEAAkE;IAClE,GAAG,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-platform-components",
3
- "version": "1.6.0",
4
- "description": "Native UI components for React Native, the real platform widgets on both iOS and Android: TextField, DatePicker, ContextMenu, SelectionMenu, SegmentedControl, TabBar, NavigationRail, Button, ButtonGroup, FloatingActionButton, FloatingToolbar and LiquidGlass. UIKit on iOS, Material 3 Expressive on Android. Fabric, TypeScript, Expo config plugin.",
3
+ "version": "1.7.0",
4
+ "description": "Native UI components for React Native, the real platform widgets on both iOS and Android: TextField, DatePicker, ContextMenu, ActionSheet, SelectionMenu, SegmentedControl, TabBar, NavigationRail, Button, ButtonGroup, FloatingActionButton, FloatingToolbar and LiquidGlass. UIKit on iOS, Material 3 Expressive on Android. Fabric, TypeScript, Expo config plugin.",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",
7
7
  "browser": "./lib/module/index.web.js",
@@ -110,6 +110,12 @@
110
110
  "contextmenu",
111
111
  "popup-menu",
112
112
  "uicontextmenu",
113
+ "action-sheet",
114
+ "actionsheet",
115
+ "uialertcontroller",
116
+ "bottom-sheet",
117
+ "modal-bottom-sheet",
118
+ "bottomsheetdialog",
113
119
  "selection-menu",
114
120
  "dropdown",
115
121
  "picker",
@@ -241,6 +247,7 @@
241
247
  "PCSelectionMenu": "PCSelectionMenu",
242
248
  "PCDatePicker": "PCDatePicker",
243
249
  "PCContextMenu": "PCContextMenu",
250
+ "PCActionSheet": "PCActionSheet",
244
251
  "PCSegmentedControl": "PCSegmentedControl",
245
252
  "PCTabBar": "PCTabBar",
246
253
  "PCTabBarAccessory": "PCTabBarAccessory",
@@ -0,0 +1,193 @@
1
+ // ActionSheet.tsx
2
+ import React, { useCallback, useMemo } from 'react';
3
+ import type { ViewProps } from 'react-native';
4
+
5
+ import NativeActionSheet, {
6
+ type ActionSheetItem,
7
+ type ActionSheetSelectEvent,
8
+ } from './ActionSheetNativeComponent';
9
+ import type { Haptics } from './haptics';
10
+ import { resolveIcon, type PlatformIcon } from './icons';
11
+ import { warnSelectionIdentifiers } from './selectionIdentifiers';
12
+
13
+ /**
14
+ * Attributes for an action sheet action, as on a ContextMenu action.
15
+ */
16
+ export interface ActionSheetActionAttributes {
17
+ /** Draws the action in the destructive style (red) */
18
+ destructive?: boolean;
19
+ /** Shows the action dimmed; it can't be picked */
20
+ disabled?: boolean;
21
+ /** Leaves the action out */
22
+ hidden?: boolean;
23
+ }
24
+
25
+ /**
26
+ * A single action in the sheet. The fields mean what they mean on a
27
+ * ContextMenu action; a sheet has no submenus, sections or states.
28
+ */
29
+ export interface ActionSheetAction {
30
+ /** Unique, non-empty identifier passed to `onSelect` */
31
+ id: string;
32
+ /** Display title */
33
+ title: string;
34
+ /**
35
+ * Icon before the title. Android only: `UIAlertAction` has no public icon
36
+ * API, so iOS shows titles only. See {@link PlatformIcon}.
37
+ */
38
+ image?: PlatformIcon;
39
+ /** Tint color for the icon (hex string, e.g. `'#FF3B30'`). Android only. */
40
+ imageColor?: string;
41
+ /** Action attributes */
42
+ attributes?: ActionSheetActionAttributes;
43
+ /**
44
+ * Haptic played when this action is picked, in place of the component's
45
+ * `haptics` (`'none'` plays nothing). Unset uses the component's. See
46
+ * {@link Haptics}.
47
+ */
48
+ haptics?: Haptics;
49
+ /**
50
+ * Test identifier of the action's row: the `UIAlertAction`'s
51
+ * `accessibilityIdentifier` on iOS, the row's view tag on Android, so
52
+ * Detox's `by.id` finds it.
53
+ */
54
+ testID?: string;
55
+ }
56
+
57
+ export interface ActionSheetProps extends ViewProps {
58
+ /**
59
+ * Whether the sheet is presented. Controlled: set it back to `false` in
60
+ * `onSelect` and `onCancel`. Setting it to `false` while the sheet is up
61
+ * dismisses it without a callback.
62
+ */
63
+ visible: boolean;
64
+
65
+ /** Title above the actions */
66
+ title?: string;
67
+
68
+ /** Message under the title */
69
+ message?: string;
70
+
71
+ /** The actions, top to bottom */
72
+ actions: readonly ActionSheetAction[];
73
+
74
+ /**
75
+ * Title of the cancel action. iOS only: default the system's localized
76
+ * "Cancel". Android bottom sheets have no cancel row.
77
+ */
78
+ cancelTitle?: string;
79
+
80
+ /** Test identifier of the iOS cancel action. */
81
+ cancelTestID?: string;
82
+
83
+ /**
84
+ * Haptic played when the user picks an action (not on cancel); an
85
+ * action's own `haptics` wins. Default: none. See {@link Haptics}.
86
+ */
87
+ haptics?: Haptics;
88
+
89
+ /**
90
+ * Android: largest scale the sheet's text may reach with the system font
91
+ * scale, as on `Text`. Unset or `0`: no cap. iOS: `UIAlertController`
92
+ * sizes its own text with Dynamic Type.
93
+ */
94
+ maxFontSizeMultiplier?: number;
95
+
96
+ /**
97
+ * Called with the action's `id` when the user picks one. The sheet is
98
+ * already closing; set `visible` to `false`.
99
+ */
100
+ onSelect?: (id: string) => void;
101
+
102
+ /**
103
+ * Called when the sheet is dismissed without a pick: the cancel action,
104
+ * a tap outside, a swipe down or the back button. Set `visible` to
105
+ * `false`.
106
+ */
107
+ onCancel?: () => void;
108
+
109
+ /**
110
+ * Optional content, rendered in place. On iPad (and wherever UIKit shows
111
+ * the sheet as a popover) the sheet points at this view.
112
+ */
113
+ children?: React.ReactNode;
114
+
115
+ /** Test identifier */
116
+ testID?: string;
117
+ }
118
+
119
+ const flag = (value: boolean | undefined) => (value ? 'true' : 'false');
120
+
121
+ /** Flattens actions for native: hidden ones dropped, icons resolved, every field set. */
122
+ function normalizeActions(
123
+ actions: readonly ActionSheetAction[]
124
+ ): ActionSheetItem[] {
125
+ const shown = actions.filter((action) => !action.attributes?.hidden);
126
+ warnSelectionIdentifiers(
127
+ 'ActionSheet',
128
+ shown.map((action) => action.id)
129
+ );
130
+ return shown.map((action) => ({
131
+ id: action.id,
132
+ title: action.title,
133
+ ...resolveIcon(action.image),
134
+ imageColor: action.imageColor ?? '',
135
+ destructive: flag(action.attributes?.destructive),
136
+ disabled: flag(action.attributes?.disabled),
137
+ haptics: action.haptics ?? '',
138
+ testID: action.testID ?? '',
139
+ }));
140
+ }
141
+
142
+ export function ActionSheet(props: ActionSheetProps): React.ReactElement {
143
+ const {
144
+ visible,
145
+ title,
146
+ message,
147
+ actions,
148
+ cancelTitle,
149
+ cancelTestID,
150
+ haptics,
151
+ maxFontSizeMultiplier,
152
+ onSelect,
153
+ onCancel,
154
+ children,
155
+ ...viewProps
156
+ } = props;
157
+
158
+ const nativeActions = useMemo(() => normalizeActions(actions), [actions]);
159
+
160
+ const handleSelect = useCallback(
161
+ (e: { nativeEvent: ActionSheetSelectEvent }) => {
162
+ const { actionId } = e.nativeEvent;
163
+ const action = actions.find((a) => a.id === actionId);
164
+ // Only actions that were shown and enabled can be picked.
165
+ if (!action || action.attributes?.hidden || action.attributes?.disabled)
166
+ return;
167
+ onSelect?.(actionId);
168
+ },
169
+ [actions, onSelect]
170
+ );
171
+
172
+ const handleCancel = useCallback(() => {
173
+ onCancel?.();
174
+ }, [onCancel]);
175
+
176
+ return (
177
+ <NativeActionSheet
178
+ visible={visible ? 'open' : 'closed'}
179
+ title={title ?? ''}
180
+ message={message ?? ''}
181
+ actions={nativeActions}
182
+ cancelTitle={cancelTitle ?? ''}
183
+ cancelTestID={cancelTestID ?? ''}
184
+ haptics={haptics ?? ''}
185
+ maxFontSizeMultiplier={maxFontSizeMultiplier ?? 0}
186
+ onSelect={onSelect ? handleSelect : undefined}
187
+ onCancel={onCancel ? handleCancel : undefined}
188
+ {...viewProps}
189
+ >
190
+ {children}
191
+ </NativeActionSheet>
192
+ );
193
+ }
@@ -0,0 +1,94 @@
1
+ // ActionSheetNativeComponent.ts
2
+ import type { HostComponent, ViewProps } from 'react-native';
3
+ import { codegenNativeComponent } from 'react-native';
4
+ import type { BubblingEventHandler, Double } from './codegenTypes';
5
+
6
+ /**
7
+ * One action of the sheet. The list is flat (no submenus or sections) and
8
+ * hidden actions are already dropped. Every field is set; empty strings mean
9
+ * "none" and flags are 'true' | 'false'.
10
+ */
11
+ export type ActionSheetItem = Readonly<{
12
+ /** Unique identifier returned by onSelect */
13
+ id: string;
14
+ title: string;
15
+ /** '' | 'sfSymbol' | 'drawable' | 'image' (Android draws icons; iOS has no public icon API) */
16
+ iconType: string;
17
+ /** SF Symbol / asset name (iOS) or drawable resource name (Android) */
18
+ iconName: string;
19
+ /** Resolved image URI when iconType === 'image' */
20
+ iconRequest: string;
21
+ iconUri: string;
22
+ /** Resolved image scale when iconType === 'image' */
23
+ iconScale: Double;
24
+ /** 'true' | 'false': draw the image as a tinted template */
25
+ iconTinted: string;
26
+ /** Tint color for the icon (hex string, e.g., "#FF0000") */
27
+ imageColor: string;
28
+ /** 'true' | 'false' */
29
+ destructive: string;
30
+ /** 'true' | 'false' */
31
+ disabled: string;
32
+ /** The action's own haptics; '' = the component's */
33
+ haptics: string;
34
+ /** accessibilityIdentifier (iOS) / view tag (Android) of the row */
35
+ testID: string;
36
+ }>;
37
+
38
+ /**
39
+ * Event emitted when the user picks an action.
40
+ */
41
+ export type ActionSheetSelectEvent = Readonly<{
42
+ /** The action's unique identifier */
43
+ actionId: string;
44
+ }>;
45
+
46
+ /** Visibility state (no booleans for codegen). */
47
+ export type ActionSheetVisible = 'open' | 'closed';
48
+
49
+ export interface ActionSheetProps extends ViewProps {
50
+ /**
51
+ * 'open' presents the sheet, 'closed' dismisses it.
52
+ */
53
+ visible?: string; // ActionSheetVisible
54
+
55
+ /** Sheet title; '' = none */
56
+ title?: string;
57
+
58
+ /** Sheet message under the title; '' = none */
59
+ message?: string;
60
+
61
+ /**
62
+ * The actions, flat.
63
+ */
64
+ actions: ReadonlyArray<ActionSheetItem>;
65
+
66
+ /** Title of the iOS cancel action; '' = the localized system "Cancel" */
67
+ cancelTitle?: string;
68
+
69
+ /** accessibilityIdentifier of the iOS cancel action */
70
+ cancelTestID?: string;
71
+
72
+ /**
73
+ * Haptic played when an action is picked: '' (none added) | 'none' | 'selection' |
74
+ * 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error'
75
+ */
76
+ haptics?: string;
77
+
78
+ /** Android: largest font scale the sheet's text may reach; 0 = no cap. */
79
+ maxFontSizeMultiplier?: Double;
80
+
81
+ /**
82
+ * Fired when the user picks an action.
83
+ */
84
+ onSelect?: BubblingEventHandler<ActionSheetSelectEvent>;
85
+
86
+ /**
87
+ * Fired when the sheet is dismissed without a pick.
88
+ */
89
+ onCancel?: BubblingEventHandler<Readonly<{}>>;
90
+ }
91
+
92
+ export default codegenNativeComponent<ActionSheetProps>(
93
+ 'PCActionSheet'
94
+ ) as HostComponent<ActionSheetProps>;
@@ -75,6 +75,8 @@ export type ButtonGroupMenuItem = Readonly<{
75
75
  state: string;
76
76
  /** The action's own haptics; '' = the component's */
77
77
  haptics: string;
78
+ /** Test identifier of the menu row; '' = none */
79
+ testID: string;
78
80
  }>;
79
81
 
80
82
  /** Event emitted when a split button menu item is picked. */
@@ -59,6 +59,8 @@ export type ButtonMenuItem = Readonly<{
59
59
  state: string;
60
60
  /** The action's own haptics; '' = the component's */
61
61
  haptics: string;
62
+ /** Test identifier of the menu row; '' = none */
63
+ testID: string;
62
64
  }>;
63
65
 
64
66
  /** Event emitted when a toggle button is pressed. */
@@ -1,13 +1,17 @@
1
1
  // ContextMenu.tsx
2
- import React, { useCallback, useMemo } from 'react';
3
- import { type ViewProps } from 'react-native';
2
+ import React, { useCallback, useMemo, useRef } from 'react';
3
+ import { type GestureResponderEvent, type ViewProps } from 'react-native';
4
4
 
5
5
  import NativeContextMenu, {
6
+ Commands,
6
7
  type ContextMenuPressActionEvent,
7
8
  } from './ContextMenuNativeComponent';
8
9
  import { flattenMenuActions, type ContextMenuAction } from './menuItems';
9
10
  import type { Haptics } from './haptics';
10
11
 
12
+ /** How far (in points) a tap may move before it no longer opens the menu. */
13
+ const TAP_SLOP = 10;
14
+
11
15
  export type {
12
16
  ContextMenuAction,
13
17
  ContextMenuActionAttributes,
@@ -25,10 +29,28 @@ export interface ContextMenuProps extends ViewProps {
25
29
 
26
30
  /**
27
31
  * How the menu is triggered:
28
- * - 'longPress' (default): Long-press opens the menu
29
- * - 'tap': Single tap opens the menu
32
+ * - 'longPress' (default): Long-press opens the menu, also on a button
33
+ * inside the content; taps still reach the content's buttons
34
+ * - 'tap': Single tap opens the menu. A tap on a pressable inside the
35
+ * content goes to that pressable instead
36
+ * - 'none': Only `visible` opens the menu. The wrapped content keeps all
37
+ * its touches, so it can open the menu from one of its own buttons.
38
+ */
39
+ trigger?: 'longPress' | 'tap' | 'none';
40
+
41
+ /**
42
+ * Opens the menu from JS, anchored to the wrapped content. Controlled:
43
+ * set it to true to open the menu, and back to false in `onMenuClose`,
44
+ * which fires however the menu closes (an action, a tap outside, or
45
+ * `visible` turning false). False dismisses an open menu. Leave it unset
46
+ * to leave the menu to the user; menus the user opens still call
47
+ * `onMenuOpen` and `onMenuClose`.
48
+ *
49
+ * iOS 17.4+ (`UIControl.performPrimaryAction()` on an invisible anchor
50
+ * button); earlier iOS has no public API to open a menu without a touch,
51
+ * so `visible` does nothing there.
30
52
  */
31
- trigger?: 'longPress' | 'tap';
53
+ visible?: boolean;
32
54
 
33
55
  /**
34
56
  * Haptic played when the user presses an action. Opening the menu keeps
@@ -74,9 +96,8 @@ export interface ContextMenuProps extends ViewProps {
74
96
  */
75
97
  anchorPosition?: 'left' | 'right';
76
98
  /**
77
- * Programmatic visibility control (Android only).
78
- * Set to true to open the menu, false to close it.
79
- * Note: iOS does not support programmatic menu opening.
99
+ * @deprecated Use the top-level `visible`, which also works on iOS.
100
+ * When both are set, the top-level one wins.
80
101
  */
81
102
  visible?: boolean;
82
103
  };
@@ -92,6 +113,7 @@ export function ContextMenu(props: ContextMenuProps): React.ReactElement {
92
113
  actions,
93
114
  disabled,
94
115
  trigger = 'longPress',
116
+ visible,
95
117
  haptics,
96
118
  onPressAction,
97
119
  onMenuOpen,
@@ -105,6 +127,40 @@ export function ContextMenu(props: ContextMenuProps): React.ReactElement {
105
127
 
106
128
  const nativeActions = useMemo(() => flattenMenuActions(actions), [actions]);
107
129
 
130
+ const nativeRef = useRef<React.ComponentRef<typeof NativeContextMenu>>(null);
131
+ // Where the current tap went down; null once it moved too far
132
+ const tapStart = useRef<{ x: number; y: number } | null>(null);
133
+
134
+ // trigger 'tap': React Native gives a touch to the deepest view that asks
135
+ // for it, so the content's own pressables keep their taps. A tap none of
136
+ // them took bubbles up to this view, and opens the menu.
137
+ const tapHandlers = useMemo(() => {
138
+ if (trigger !== 'tap' || disabled) return undefined;
139
+ return {
140
+ onStartShouldSetResponder: () => true,
141
+ onResponderGrant: (e: GestureResponderEvent) => {
142
+ tapStart.current = { x: e.nativeEvent.pageX, y: e.nativeEvent.pageY };
143
+ },
144
+ onResponderMove: (e: GestureResponderEvent) => {
145
+ const start = tapStart.current;
146
+ if (!start) return;
147
+ const { pageX, pageY } = e.nativeEvent;
148
+ if (Math.hypot(pageX - start.x, pageY - start.y) > TAP_SLOP) {
149
+ tapStart.current = null;
150
+ }
151
+ },
152
+ onResponderRelease: () => {
153
+ const node = nativeRef.current;
154
+ if (tapStart.current && node != null) Commands.handleTap(node);
155
+ tapStart.current = null;
156
+ },
157
+ // A scroll view took the touch over
158
+ onResponderTerminate: () => {
159
+ tapStart.current = null;
160
+ },
161
+ };
162
+ }, [trigger, disabled]);
163
+
108
164
  const handlePressAction = useCallback(
109
165
  (e: { nativeEvent: ContextMenuPressActionEvent }) => {
110
166
  const { actionId, actionTitle } = e.nativeEvent;
@@ -134,19 +190,22 @@ export function ContextMenu(props: ContextMenuProps): React.ReactElement {
134
190
 
135
191
  const nativeAndroid = useMemo(() => {
136
192
  if (!android) return undefined;
137
- return {
138
- anchorPosition: android.anchorPosition,
139
- visible: android.visible ? 'open' : 'closed',
140
- };
193
+ return { anchorPosition: android.anchorPosition };
141
194
  }, [android]);
142
195
 
196
+ // The deprecated android.visible still works, under the top-level prop
197
+ const open = visible ?? android?.visible;
198
+
143
199
  return (
144
200
  <NativeContextMenu
201
+ ref={nativeRef}
202
+ {...tapHandlers}
145
203
  style={style}
146
204
  title={title}
147
205
  actions={nativeActions}
148
206
  interactivity={disabled ? 'disabled' : 'enabled'}
149
207
  trigger={trigger}
208
+ visible={open === undefined ? undefined : open ? 'open' : 'closed'}
150
209
  haptics={haptics ?? ''}
151
210
  onPressAction={onPressAction ? handlePressAction : undefined}
152
211
  onMenuOpen={onMenuOpen ? handleMenuOpen : undefined}