react-native-platform-components 1.4.0 → 1.5.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 (598) hide show
  1. package/PlatformComponents.podspec +1 -1
  2. package/README.md +33 -31
  3. package/android/src/main/java/com/platformcomponents/PCButtonGroupView.kt +175 -9
  4. package/android/src/main/java/com/platformcomponents/PCButtonGroupViewManager.kt +52 -2
  5. package/android/src/main/java/com/platformcomponents/PCButtonSupport.kt +44 -12
  6. package/android/src/main/java/com/platformcomponents/PCButtonView.kt +187 -5
  7. package/android/src/main/java/com/platformcomponents/PCButtonViewManager.kt +85 -7
  8. package/android/src/main/java/com/platformcomponents/PCContextMenuView.kt +41 -151
  9. package/android/src/main/java/com/platformcomponents/PCContextMenuViewManager.kt +7 -63
  10. package/android/src/main/java/com/platformcomponents/PCDatePickerView.kt +310 -115
  11. package/android/src/main/java/com/platformcomponents/PCDatePickerViewManager.kt +23 -3
  12. package/android/src/main/java/com/platformcomponents/PCExpressive.kt +6 -1
  13. package/android/src/main/java/com/platformcomponents/PCFloatingActionButtonView.kt +485 -0
  14. package/android/src/main/java/com/platformcomponents/PCFloatingActionButtonViewManager.kt +109 -0
  15. package/android/src/main/java/com/platformcomponents/PCFloatingToolbarView.kt +132 -0
  16. package/android/src/main/java/com/platformcomponents/PCFloatingToolbarViewManager.kt +8 -0
  17. package/android/src/main/java/com/platformcomponents/PCHaptics.kt +46 -0
  18. package/android/src/main/java/com/platformcomponents/PCImageLoader.kt +42 -7
  19. package/android/src/main/java/com/platformcomponents/PCLiquidGlassContainerView.kt +32 -0
  20. package/android/src/main/java/com/platformcomponents/PCLiquidGlassContainerViewManager.kt +31 -0
  21. package/android/src/main/java/com/platformcomponents/PCLiquidGlassView.kt +32 -6
  22. package/android/src/main/java/com/platformcomponents/PCLiquidGlassViewManager.kt +4 -0
  23. package/android/src/main/java/com/platformcomponents/PCMenuSupport.kt +280 -0
  24. package/android/src/main/java/com/platformcomponents/PCNavigationBarSupport.kt +332 -0
  25. package/android/src/main/java/com/platformcomponents/PCNavigationRailView.kt +448 -0
  26. package/android/src/main/java/com/platformcomponents/PCNavigationRailViewManager.kt +176 -0
  27. package/android/src/main/java/com/platformcomponents/PCSegmentedControlView.kt +24 -14
  28. package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +14 -2
  29. package/android/src/main/java/com/platformcomponents/PCSelectionMenuView.kt +371 -39
  30. package/android/src/main/java/com/platformcomponents/PCSelectionMenuViewManager.kt +18 -4
  31. package/android/src/main/java/com/platformcomponents/PCTabBarView.kt +397 -0
  32. package/android/src/main/java/com/platformcomponents/PCTabBarViewManager.kt +182 -0
  33. package/android/src/main/java/com/platformcomponents/PCTextFieldView.kt +415 -40
  34. package/android/src/main/java/com/platformcomponents/PCTextFieldViewManager.kt +109 -3
  35. package/android/src/main/java/com/platformcomponents/PCThemeSupport.kt +37 -0
  36. package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +4 -0
  37. package/android/src/main/res/drawable/pc_ic_search.xml +12 -0
  38. package/android/src/main/res/values/ids.xml +5 -0
  39. package/android/src/main/res/values/styles.xml +24 -0
  40. package/ios/PCButton.mm +122 -7
  41. package/ios/PCButtonGroup.mm +68 -1
  42. package/ios/PCButtonGroupView.swift +225 -6
  43. package/ios/PCButtonSupport.swift +181 -10
  44. package/ios/PCButtonView.swift +297 -14
  45. package/ios/PCConstants.swift +23 -2
  46. package/ios/PCContextMenu.mm +28 -110
  47. package/ios/PCContextMenu.swift +106 -167
  48. package/ios/PCDatePicker.mm +21 -9
  49. package/ios/PCDatePickerView.swift +94 -20
  50. package/ios/PCFloatingActionButton.h +10 -0
  51. package/ios/PCFloatingActionButton.mm +177 -0
  52. package/ios/PCFloatingActionButtonView.swift +426 -0
  53. package/ios/PCFloatingToolbar.mm +27 -0
  54. package/ios/PCFloatingToolbarView.swift +241 -0
  55. package/ios/PCHaptics.swift +91 -0
  56. package/ios/PCImageLoader.swift +76 -12
  57. package/ios/PCLiquidGlass.mm +36 -0
  58. package/ios/PCLiquidGlass.swift +221 -114
  59. package/ios/PCLiquidGlassContainer.h +10 -0
  60. package/ios/PCLiquidGlassContainer.mm +84 -0
  61. package/ios/PCLiquidGlassContainer.swift +69 -0
  62. package/ios/PCMenuItems.h +76 -0
  63. package/ios/PCMenuSupport.swift +350 -0
  64. package/ios/PCNavigationRail.h +10 -0
  65. package/ios/PCNavigationRail.mm +270 -0
  66. package/ios/PCNavigationRailView.swift +415 -0
  67. package/ios/PCSegmentedControl.mm +17 -2
  68. package/ios/PCSegmentedControl.swift +57 -7
  69. package/ios/PCSelectionMenu.mm +36 -8
  70. package/ios/PCSelectionMenu.swift +224 -48
  71. package/ios/PCTabBar.h +10 -0
  72. package/ios/PCTabBar.mm +285 -0
  73. package/ios/PCTabBarAccessory.h +10 -0
  74. package/ios/PCTabBarAccessory.mm +93 -0
  75. package/ios/PCTabBarAccessoryView.swift +96 -0
  76. package/ios/PCTabBarView.swift +671 -0
  77. package/ios/PCTextField.mm +159 -4
  78. package/ios/PCTextFieldView.swift +603 -57
  79. package/lib/commonjs/Button.js +73 -1
  80. package/lib/commonjs/Button.js.map +1 -1
  81. package/lib/commonjs/ButtonGroup.js +13 -3
  82. package/lib/commonjs/ButtonGroup.js.map +1 -1
  83. package/lib/commonjs/ButtonGroupNativeComponent.ts +74 -4
  84. package/lib/commonjs/ButtonNativeComponent.ts +119 -3
  85. package/lib/commonjs/ContextMenu.js +9 -48
  86. package/lib/commonjs/ContextMenu.js.map +1 -1
  87. package/lib/commonjs/ContextMenuNativeComponent.ts +47 -49
  88. package/lib/commonjs/DatePicker.js +98 -2
  89. package/lib/commonjs/DatePicker.js.map +1 -1
  90. package/lib/commonjs/DatePickerNativeComponent.ts +19 -2
  91. package/lib/commonjs/FloatingActionButton.js +60 -0
  92. package/lib/commonjs/FloatingActionButton.js.map +1 -0
  93. package/lib/commonjs/FloatingActionButtonNativeComponent.ts +58 -0
  94. package/lib/commonjs/FloatingToolbar.js +9 -1
  95. package/lib/commonjs/FloatingToolbar.js.map +1 -1
  96. package/lib/commonjs/FloatingToolbarNativeComponent.ts +16 -0
  97. package/lib/commonjs/LiquidGlass.js +7 -1
  98. package/lib/commonjs/LiquidGlass.js.map +1 -1
  99. package/lib/commonjs/LiquidGlassContainer.js +32 -0
  100. package/lib/commonjs/LiquidGlassContainer.js.map +1 -0
  101. package/lib/commonjs/LiquidGlassContainerNativeComponent.ts +17 -0
  102. package/lib/commonjs/LiquidGlassNativeComponent.ts +8 -0
  103. package/lib/commonjs/NavigationRail.js +104 -0
  104. package/lib/commonjs/NavigationRail.js.map +1 -0
  105. package/lib/commonjs/NavigationRailNativeComponent.ts +107 -0
  106. package/lib/commonjs/PlatformComponentsProvider.js +18 -0
  107. package/lib/commonjs/PlatformComponentsProvider.js.map +1 -0
  108. package/lib/commonjs/SegmentedControl.js +7 -0
  109. package/lib/commonjs/SegmentedControl.js.map +1 -1
  110. package/lib/commonjs/SegmentedControlNativeComponent.ts +11 -0
  111. package/lib/commonjs/SelectionMenu.js +27 -3
  112. package/lib/commonjs/SelectionMenu.js.map +1 -1
  113. package/lib/commonjs/SelectionMenuNativeComponent.ts +26 -4
  114. package/lib/commonjs/SplitButton.js +98 -0
  115. package/lib/commonjs/SplitButton.js.map +1 -0
  116. package/lib/commonjs/TabBar.js +203 -0
  117. package/lib/commonjs/TabBar.js.map +1 -0
  118. package/lib/commonjs/TabBarAccessoryNativeComponent.ts +19 -0
  119. package/lib/commonjs/TabBarNativeComponent.ts +145 -0
  120. package/lib/commonjs/TextField.js +171 -8
  121. package/lib/commonjs/TextField.js.map +1 -1
  122. package/lib/commonjs/TextFieldNativeComponent.ts +110 -4
  123. package/lib/commonjs/focusRegistry.js +2 -1
  124. package/lib/commonjs/focusRegistry.js.map +1 -1
  125. package/lib/commonjs/haptics.js +2 -0
  126. package/lib/commonjs/haptics.js.map +1 -0
  127. package/lib/commonjs/icons.js +15 -1
  128. package/lib/commonjs/icons.js.map +1 -1
  129. package/lib/commonjs/index.js +77 -0
  130. package/lib/commonjs/index.js.map +1 -1
  131. package/lib/commonjs/index.web.js +156 -92
  132. package/lib/commonjs/index.web.js.map +1 -1
  133. package/lib/commonjs/jest.js +910 -0
  134. package/lib/commonjs/jest.js.map +1 -0
  135. package/lib/commonjs/menuItems.js +68 -0
  136. package/lib/commonjs/menuItems.js.map +1 -0
  137. package/lib/commonjs/selectionIdentifiers.js +18 -0
  138. package/lib/commonjs/selectionIdentifiers.js.map +1 -0
  139. package/lib/commonjs/submitBehavior.js +19 -0
  140. package/lib/commonjs/submitBehavior.js.map +1 -0
  141. package/lib/commonjs/tabItems.js +49 -0
  142. package/lib/commonjs/tabItems.js.map +1 -0
  143. package/lib/commonjs/web/Button.js +170 -0
  144. package/lib/commonjs/web/Button.js.map +1 -0
  145. package/lib/commonjs/web/ButtonGroup.js +119 -0
  146. package/lib/commonjs/web/ButtonGroup.js.map +1 -0
  147. package/lib/commonjs/web/DatePicker.js +168 -0
  148. package/lib/commonjs/web/DatePicker.js.map +1 -0
  149. package/lib/commonjs/web/DateRangePicker.js +137 -0
  150. package/lib/commonjs/web/DateRangePicker.js.map +1 -0
  151. package/lib/commonjs/web/Dialog.js +54 -0
  152. package/lib/commonjs/web/Dialog.js.map +1 -0
  153. package/lib/commonjs/web/FloatingActionButton.js +98 -0
  154. package/lib/commonjs/web/FloatingActionButton.js.map +1 -0
  155. package/lib/commonjs/web/Icon.js +34 -0
  156. package/lib/commonjs/web/Icon.js.map +1 -0
  157. package/lib/commonjs/web/NativeTheme.js +28 -0
  158. package/lib/commonjs/web/NativeTheme.js.map +1 -0
  159. package/lib/commonjs/web/NavigationRail.js +139 -0
  160. package/lib/commonjs/web/NavigationRail.js.map +1 -0
  161. package/lib/commonjs/web/PlatformComponentsProvider.js +51 -0
  162. package/lib/commonjs/web/PlatformComponentsProvider.js.map +1 -0
  163. package/lib/commonjs/web/SegmentedControl.js +117 -0
  164. package/lib/commonjs/web/SegmentedControl.js.map +1 -0
  165. package/lib/commonjs/web/SelectionMenu.js +142 -0
  166. package/lib/commonjs/web/SelectionMenu.js.map +1 -0
  167. package/lib/commonjs/web/SplitButton.js +35 -0
  168. package/lib/commonjs/web/SplitButton.js.map +1 -0
  169. package/lib/commonjs/web/TabBar.js +131 -0
  170. package/lib/commonjs/web/TabBar.js.map +1 -0
  171. package/lib/commonjs/web/TextField.js +322 -0
  172. package/lib/commonjs/web/TextField.js.map +1 -0
  173. package/lib/commonjs/web/components.js +36 -0
  174. package/lib/commonjs/web/components.js.map +1 -0
  175. package/lib/commonjs/web/containers.js +121 -0
  176. package/lib/commonjs/web/containers.js.map +1 -0
  177. package/lib/commonjs/web/dateInput.js +116 -0
  178. package/lib/commonjs/web/dateInput.js.map +1 -0
  179. package/lib/commonjs/web/shared.js +192 -0
  180. package/lib/commonjs/web/shared.js.map +1 -0
  181. package/lib/commonjs/webComponents.js +6 -0
  182. package/lib/commonjs/webComponents.js.map +1 -0
  183. package/lib/module/Button.js +74 -2
  184. package/lib/module/Button.js.map +1 -1
  185. package/lib/module/ButtonGroup.js +13 -3
  186. package/lib/module/ButtonGroup.js.map +1 -1
  187. package/lib/module/ButtonGroupNativeComponent.ts +74 -4
  188. package/lib/module/ButtonNativeComponent.ts +119 -3
  189. package/lib/module/ContextMenu.js +9 -48
  190. package/lib/module/ContextMenu.js.map +1 -1
  191. package/lib/module/ContextMenuNativeComponent.ts +47 -49
  192. package/lib/module/DatePicker.js +98 -4
  193. package/lib/module/DatePicker.js.map +1 -1
  194. package/lib/module/DatePickerNativeComponent.ts +19 -2
  195. package/lib/module/FloatingActionButton.js +53 -0
  196. package/lib/module/FloatingActionButton.js.map +1 -0
  197. package/lib/module/FloatingActionButtonNativeComponent.ts +58 -0
  198. package/lib/module/FloatingToolbar.js +9 -1
  199. package/lib/module/FloatingToolbar.js.map +1 -1
  200. package/lib/module/FloatingToolbarNativeComponent.ts +16 -0
  201. package/lib/module/LiquidGlass.js +7 -1
  202. package/lib/module/LiquidGlass.js.map +1 -1
  203. package/lib/module/LiquidGlassContainer.js +26 -0
  204. package/lib/module/LiquidGlassContainer.js.map +1 -0
  205. package/lib/module/LiquidGlassContainerNativeComponent.ts +17 -0
  206. package/lib/module/LiquidGlassNativeComponent.ts +8 -0
  207. package/lib/module/NavigationRail.js +99 -0
  208. package/lib/module/NavigationRail.js.map +1 -0
  209. package/lib/module/NavigationRailNativeComponent.ts +107 -0
  210. package/lib/module/PlatformComponentsProvider.js +13 -0
  211. package/lib/module/PlatformComponentsProvider.js.map +1 -0
  212. package/lib/module/SegmentedControl.js +9 -1
  213. package/lib/module/SegmentedControl.js.map +1 -1
  214. package/lib/module/SegmentedControlNativeComponent.ts +11 -0
  215. package/lib/module/SelectionMenu.js +27 -3
  216. package/lib/module/SelectionMenu.js.map +1 -1
  217. package/lib/module/SelectionMenuNativeComponent.ts +26 -4
  218. package/lib/module/SplitButton.js +91 -0
  219. package/lib/module/SplitButton.js.map +1 -0
  220. package/lib/module/TabBar.js +196 -0
  221. package/lib/module/TabBar.js.map +1 -0
  222. package/lib/module/TabBarAccessoryNativeComponent.ts +19 -0
  223. package/lib/module/TabBarNativeComponent.ts +145 -0
  224. package/lib/module/TextField.js +172 -9
  225. package/lib/module/TextField.js.map +1 -1
  226. package/lib/module/TextFieldNativeComponent.ts +110 -4
  227. package/lib/module/focusRegistry.js +1 -0
  228. package/lib/module/focusRegistry.js.map +1 -1
  229. package/lib/module/haptics.js +2 -0
  230. package/lib/module/haptics.js.map +1 -0
  231. package/lib/module/icons.js +15 -1
  232. package/lib/module/icons.js.map +1 -1
  233. package/lib/module/index.js +7 -0
  234. package/lib/module/index.js.map +1 -1
  235. package/lib/module/index.web.js +12 -87
  236. package/lib/module/index.web.js.map +1 -1
  237. package/lib/module/jest.js +840 -0
  238. package/lib/module/jest.js.map +1 -0
  239. package/lib/module/menuItems.js +65 -0
  240. package/lib/module/menuItems.js.map +1 -0
  241. package/lib/module/selectionIdentifiers.js +14 -0
  242. package/lib/module/selectionIdentifiers.js.map +1 -0
  243. package/lib/module/submitBehavior.js +15 -0
  244. package/lib/module/submitBehavior.js.map +1 -0
  245. package/lib/module/tabItems.js +45 -0
  246. package/lib/module/tabItems.js.map +1 -0
  247. package/lib/module/web/Button.js +164 -0
  248. package/lib/module/web/Button.js.map +1 -0
  249. package/lib/module/web/ButtonGroup.js +113 -0
  250. package/lib/module/web/ButtonGroup.js.map +1 -0
  251. package/lib/module/web/DatePicker.js +162 -0
  252. package/lib/module/web/DatePicker.js.map +1 -0
  253. package/lib/module/web/DateRangePicker.js +131 -0
  254. package/lib/module/web/DateRangePicker.js.map +1 -0
  255. package/lib/module/web/Dialog.js +48 -0
  256. package/lib/module/web/Dialog.js.map +1 -0
  257. package/lib/module/web/FloatingActionButton.js +94 -0
  258. package/lib/module/web/FloatingActionButton.js.map +1 -0
  259. package/lib/module/web/Icon.js +29 -0
  260. package/lib/module/web/Icon.js.map +1 -0
  261. package/lib/module/web/NativeTheme.js +23 -0
  262. package/lib/module/web/NativeTheme.js.map +1 -0
  263. package/lib/module/web/NavigationRail.js +133 -0
  264. package/lib/module/web/NavigationRail.js.map +1 -0
  265. package/lib/module/web/PlatformComponentsProvider.js +44 -0
  266. package/lib/module/web/PlatformComponentsProvider.js.map +1 -0
  267. package/lib/module/web/SegmentedControl.js +112 -0
  268. package/lib/module/web/SegmentedControl.js.map +1 -0
  269. package/lib/module/web/SelectionMenu.js +137 -0
  270. package/lib/module/web/SelectionMenu.js.map +1 -0
  271. package/lib/module/web/SplitButton.js +30 -0
  272. package/lib/module/web/SplitButton.js.map +1 -0
  273. package/lib/module/web/TabBar.js +126 -0
  274. package/lib/module/web/TabBar.js.map +1 -0
  275. package/lib/module/web/TextField.js +316 -0
  276. package/lib/module/web/TextField.js.map +1 -0
  277. package/lib/module/web/components.js +33 -0
  278. package/lib/module/web/components.js.map +1 -0
  279. package/lib/module/web/containers.js +112 -0
  280. package/lib/module/web/containers.js.map +1 -0
  281. package/lib/module/web/dateInput.js +109 -0
  282. package/lib/module/web/dateInput.js.map +1 -0
  283. package/lib/module/web/shared.js +179 -0
  284. package/lib/module/web/shared.js.map +1 -0
  285. package/lib/module/webComponents.js +4 -0
  286. package/lib/module/webComponents.js.map +1 -0
  287. package/lib/typescript/commonjs/docs/sidebars.d.ts.map +1 -1
  288. package/lib/typescript/commonjs/src/Button.d.ts +111 -3
  289. package/lib/typescript/commonjs/src/Button.d.ts.map +1 -1
  290. package/lib/typescript/commonjs/src/ButtonGroup.d.ts +21 -6
  291. package/lib/typescript/commonjs/src/ButtonGroup.d.ts.map +1 -1
  292. package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts +64 -3
  293. package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts.map +1 -1
  294. package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts +94 -3
  295. package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts.map +1 -1
  296. package/lib/typescript/commonjs/src/ContextMenu.d.ts +20 -33
  297. package/lib/typescript/commonjs/src/ContextMenu.d.ts.map +1 -1
  298. package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts +45 -47
  299. package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts.map +1 -1
  300. package/lib/typescript/commonjs/src/DatePicker.d.ts +74 -1
  301. package/lib/typescript/commonjs/src/DatePicker.d.ts.map +1 -1
  302. package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts +16 -1
  303. package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts.map +1 -1
  304. package/lib/typescript/commonjs/src/FloatingActionButton.d.ts +67 -0
  305. package/lib/typescript/commonjs/src/FloatingActionButton.d.ts.map +1 -0
  306. package/lib/typescript/commonjs/src/FloatingActionButtonNativeComponent.d.ts +43 -0
  307. package/lib/typescript/commonjs/src/FloatingActionButtonNativeComponent.d.ts.map +1 -0
  308. package/lib/typescript/commonjs/src/FloatingToolbar.d.ts +30 -0
  309. package/lib/typescript/commonjs/src/FloatingToolbar.d.ts.map +1 -1
  310. package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts +12 -0
  311. package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts.map +1 -1
  312. package/lib/typescript/commonjs/src/LiquidGlass.d.ts +17 -0
  313. package/lib/typescript/commonjs/src/LiquidGlass.d.ts.map +1 -1
  314. package/lib/typescript/commonjs/src/LiquidGlassContainer.d.ts +27 -0
  315. package/lib/typescript/commonjs/src/LiquidGlassContainer.d.ts.map +1 -0
  316. package/lib/typescript/commonjs/src/LiquidGlassContainerNativeComponent.d.ts +13 -0
  317. package/lib/typescript/commonjs/src/LiquidGlassContainerNativeComponent.d.ts.map +1 -0
  318. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts +7 -0
  319. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts.map +1 -1
  320. package/lib/typescript/commonjs/src/NavigationRail.d.ts +86 -0
  321. package/lib/typescript/commonjs/src/NavigationRail.d.ts.map +1 -0
  322. package/lib/typescript/commonjs/src/NavigationRailNativeComponent.d.ts +81 -0
  323. package/lib/typescript/commonjs/src/NavigationRailNativeComponent.d.ts.map +1 -0
  324. package/lib/typescript/commonjs/src/PlatformComponentsProvider.d.ts +6 -0
  325. package/lib/typescript/commonjs/src/PlatformComponentsProvider.d.ts.map +1 -0
  326. package/lib/typescript/commonjs/src/SegmentedControl.d.ts +18 -1
  327. package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -1
  328. package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +9 -0
  329. package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -1
  330. package/lib/typescript/commonjs/src/SelectionMenu.d.ts +44 -2
  331. package/lib/typescript/commonjs/src/SelectionMenu.d.ts.map +1 -1
  332. package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts +20 -4
  333. package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts.map +1 -1
  334. package/lib/typescript/commonjs/src/SplitButton.d.ts +83 -0
  335. package/lib/typescript/commonjs/src/SplitButton.d.ts.map +1 -0
  336. package/lib/typescript/commonjs/src/TabBar.d.ts +144 -0
  337. package/lib/typescript/commonjs/src/TabBar.d.ts.map +1 -0
  338. package/lib/typescript/commonjs/src/TabBarAccessoryNativeComponent.d.ts +13 -0
  339. package/lib/typescript/commonjs/src/TabBarAccessoryNativeComponent.d.ts.map +1 -0
  340. package/lib/typescript/commonjs/src/TabBarNativeComponent.d.ts +110 -0
  341. package/lib/typescript/commonjs/src/TabBarNativeComponent.d.ts.map +1 -0
  342. package/lib/typescript/commonjs/src/TextField.d.ts +166 -8
  343. package/lib/typescript/commonjs/src/TextField.d.ts.map +1 -1
  344. package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts +81 -3
  345. package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts.map +1 -1
  346. package/lib/typescript/commonjs/src/focusRegistry.d.ts.map +1 -1
  347. package/lib/typescript/commonjs/src/haptics.d.ts +20 -0
  348. package/lib/typescript/commonjs/src/haptics.d.ts.map +1 -0
  349. package/lib/typescript/commonjs/src/icons.d.ts +7 -1
  350. package/lib/typescript/commonjs/src/icons.d.ts.map +1 -1
  351. package/lib/typescript/commonjs/src/index.d.ts +7 -0
  352. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  353. package/lib/typescript/commonjs/src/index.web.d.ts +25 -254
  354. package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
  355. package/lib/typescript/commonjs/src/jest.d.ts +139 -0
  356. package/lib/typescript/commonjs/src/jest.d.ts.map +1 -0
  357. package/lib/typescript/commonjs/src/menuItems.d.ts +100 -0
  358. package/lib/typescript/commonjs/src/menuItems.d.ts.map +1 -0
  359. package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts +3 -0
  360. package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts.map +1 -0
  361. package/lib/typescript/commonjs/src/submitBehavior.d.ts +9 -0
  362. package/lib/typescript/commonjs/src/submitBehavior.d.ts.map +1 -0
  363. package/lib/typescript/commonjs/src/tabItems.d.ts +55 -0
  364. package/lib/typescript/commonjs/src/tabItems.d.ts.map +1 -0
  365. package/lib/typescript/commonjs/src/web/Button.d.ts +9 -0
  366. package/lib/typescript/commonjs/src/web/Button.d.ts.map +1 -0
  367. package/lib/typescript/commonjs/src/web/ButtonGroup.d.ts +11 -0
  368. package/lib/typescript/commonjs/src/web/ButtonGroup.d.ts.map +1 -0
  369. package/lib/typescript/commonjs/src/web/DatePicker.d.ts +14 -0
  370. package/lib/typescript/commonjs/src/web/DatePicker.d.ts.map +1 -0
  371. package/lib/typescript/commonjs/src/web/DateRangePicker.d.ts +11 -0
  372. package/lib/typescript/commonjs/src/web/DateRangePicker.d.ts.map +1 -0
  373. package/lib/typescript/commonjs/src/web/Dialog.d.ts +12 -0
  374. package/lib/typescript/commonjs/src/web/Dialog.d.ts.map +1 -0
  375. package/lib/typescript/commonjs/src/web/FloatingActionButton.d.ts +8 -0
  376. package/lib/typescript/commonjs/src/web/FloatingActionButton.d.ts.map +1 -0
  377. package/lib/typescript/commonjs/src/web/Icon.d.ts +12 -0
  378. package/lib/typescript/commonjs/src/web/Icon.d.ts.map +1 -0
  379. package/lib/typescript/commonjs/src/web/NativeTheme.d.ts +10 -0
  380. package/lib/typescript/commonjs/src/web/NativeTheme.d.ts.map +1 -0
  381. package/lib/typescript/commonjs/src/web/NavigationRail.d.ts +8 -0
  382. package/lib/typescript/commonjs/src/web/NavigationRail.d.ts.map +1 -0
  383. package/lib/typescript/commonjs/src/web/PlatformComponentsProvider.d.ts +10 -0
  384. package/lib/typescript/commonjs/src/web/PlatformComponentsProvider.d.ts.map +1 -0
  385. package/lib/typescript/commonjs/src/web/SegmentedControl.d.ts +8 -0
  386. package/lib/typescript/commonjs/src/web/SegmentedControl.d.ts.map +1 -0
  387. package/lib/typescript/commonjs/src/web/SelectionMenu.d.ts +10 -0
  388. package/lib/typescript/commonjs/src/web/SelectionMenu.d.ts.map +1 -0
  389. package/lib/typescript/commonjs/src/web/SplitButton.d.ts +9 -0
  390. package/lib/typescript/commonjs/src/web/SplitButton.d.ts.map +1 -0
  391. package/lib/typescript/commonjs/src/web/TabBar.d.ts +9 -0
  392. package/lib/typescript/commonjs/src/web/TabBar.d.ts.map +1 -0
  393. package/lib/typescript/commonjs/src/web/TextField.d.ts +9 -0
  394. package/lib/typescript/commonjs/src/web/TextField.d.ts.map +1 -0
  395. package/lib/typescript/commonjs/src/web/components.d.ts +17 -0
  396. package/lib/typescript/commonjs/src/web/components.d.ts.map +1 -0
  397. package/lib/typescript/commonjs/src/web/containers.d.ts +24 -0
  398. package/lib/typescript/commonjs/src/web/containers.d.ts.map +1 -0
  399. package/lib/typescript/commonjs/src/web/dateInput.d.ts +20 -0
  400. package/lib/typescript/commonjs/src/web/dateInput.d.ts.map +1 -0
  401. package/lib/typescript/commonjs/src/web/shared.d.ts +43 -0
  402. package/lib/typescript/commonjs/src/web/shared.d.ts.map +1 -0
  403. package/lib/typescript/commonjs/src/webComponents.d.ts +43 -0
  404. package/lib/typescript/commonjs/src/webComponents.d.ts.map +1 -0
  405. package/lib/typescript/module/docs/sidebars.d.ts.map +1 -1
  406. package/lib/typescript/module/src/Button.d.ts +111 -3
  407. package/lib/typescript/module/src/Button.d.ts.map +1 -1
  408. package/lib/typescript/module/src/ButtonGroup.d.ts +21 -6
  409. package/lib/typescript/module/src/ButtonGroup.d.ts.map +1 -1
  410. package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts +64 -3
  411. package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts.map +1 -1
  412. package/lib/typescript/module/src/ButtonNativeComponent.d.ts +94 -3
  413. package/lib/typescript/module/src/ButtonNativeComponent.d.ts.map +1 -1
  414. package/lib/typescript/module/src/ContextMenu.d.ts +20 -33
  415. package/lib/typescript/module/src/ContextMenu.d.ts.map +1 -1
  416. package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts +45 -47
  417. package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts.map +1 -1
  418. package/lib/typescript/module/src/DatePicker.d.ts +74 -1
  419. package/lib/typescript/module/src/DatePicker.d.ts.map +1 -1
  420. package/lib/typescript/module/src/DatePickerNativeComponent.d.ts +16 -1
  421. package/lib/typescript/module/src/DatePickerNativeComponent.d.ts.map +1 -1
  422. package/lib/typescript/module/src/FloatingActionButton.d.ts +67 -0
  423. package/lib/typescript/module/src/FloatingActionButton.d.ts.map +1 -0
  424. package/lib/typescript/module/src/FloatingActionButtonNativeComponent.d.ts +43 -0
  425. package/lib/typescript/module/src/FloatingActionButtonNativeComponent.d.ts.map +1 -0
  426. package/lib/typescript/module/src/FloatingToolbar.d.ts +30 -0
  427. package/lib/typescript/module/src/FloatingToolbar.d.ts.map +1 -1
  428. package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts +12 -0
  429. package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts.map +1 -1
  430. package/lib/typescript/module/src/LiquidGlass.d.ts +17 -0
  431. package/lib/typescript/module/src/LiquidGlass.d.ts.map +1 -1
  432. package/lib/typescript/module/src/LiquidGlassContainer.d.ts +27 -0
  433. package/lib/typescript/module/src/LiquidGlassContainer.d.ts.map +1 -0
  434. package/lib/typescript/module/src/LiquidGlassContainerNativeComponent.d.ts +13 -0
  435. package/lib/typescript/module/src/LiquidGlassContainerNativeComponent.d.ts.map +1 -0
  436. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts +7 -0
  437. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts.map +1 -1
  438. package/lib/typescript/module/src/NavigationRail.d.ts +86 -0
  439. package/lib/typescript/module/src/NavigationRail.d.ts.map +1 -0
  440. package/lib/typescript/module/src/NavigationRailNativeComponent.d.ts +81 -0
  441. package/lib/typescript/module/src/NavigationRailNativeComponent.d.ts.map +1 -0
  442. package/lib/typescript/module/src/PlatformComponentsProvider.d.ts +6 -0
  443. package/lib/typescript/module/src/PlatformComponentsProvider.d.ts.map +1 -0
  444. package/lib/typescript/module/src/SegmentedControl.d.ts +18 -1
  445. package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -1
  446. package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +9 -0
  447. package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -1
  448. package/lib/typescript/module/src/SelectionMenu.d.ts +44 -2
  449. package/lib/typescript/module/src/SelectionMenu.d.ts.map +1 -1
  450. package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts +20 -4
  451. package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts.map +1 -1
  452. package/lib/typescript/module/src/SplitButton.d.ts +83 -0
  453. package/lib/typescript/module/src/SplitButton.d.ts.map +1 -0
  454. package/lib/typescript/module/src/TabBar.d.ts +144 -0
  455. package/lib/typescript/module/src/TabBar.d.ts.map +1 -0
  456. package/lib/typescript/module/src/TabBarAccessoryNativeComponent.d.ts +13 -0
  457. package/lib/typescript/module/src/TabBarAccessoryNativeComponent.d.ts.map +1 -0
  458. package/lib/typescript/module/src/TabBarNativeComponent.d.ts +110 -0
  459. package/lib/typescript/module/src/TabBarNativeComponent.d.ts.map +1 -0
  460. package/lib/typescript/module/src/TextField.d.ts +166 -8
  461. package/lib/typescript/module/src/TextField.d.ts.map +1 -1
  462. package/lib/typescript/module/src/TextFieldNativeComponent.d.ts +81 -3
  463. package/lib/typescript/module/src/TextFieldNativeComponent.d.ts.map +1 -1
  464. package/lib/typescript/module/src/focusRegistry.d.ts.map +1 -1
  465. package/lib/typescript/module/src/haptics.d.ts +20 -0
  466. package/lib/typescript/module/src/haptics.d.ts.map +1 -0
  467. package/lib/typescript/module/src/icons.d.ts +7 -1
  468. package/lib/typescript/module/src/icons.d.ts.map +1 -1
  469. package/lib/typescript/module/src/index.d.ts +7 -0
  470. package/lib/typescript/module/src/index.d.ts.map +1 -1
  471. package/lib/typescript/module/src/index.web.d.ts +25 -254
  472. package/lib/typescript/module/src/index.web.d.ts.map +1 -1
  473. package/lib/typescript/module/src/jest.d.ts +139 -0
  474. package/lib/typescript/module/src/jest.d.ts.map +1 -0
  475. package/lib/typescript/module/src/menuItems.d.ts +100 -0
  476. package/lib/typescript/module/src/menuItems.d.ts.map +1 -0
  477. package/lib/typescript/module/src/selectionIdentifiers.d.ts +3 -0
  478. package/lib/typescript/module/src/selectionIdentifiers.d.ts.map +1 -0
  479. package/lib/typescript/module/src/submitBehavior.d.ts +9 -0
  480. package/lib/typescript/module/src/submitBehavior.d.ts.map +1 -0
  481. package/lib/typescript/module/src/tabItems.d.ts +55 -0
  482. package/lib/typescript/module/src/tabItems.d.ts.map +1 -0
  483. package/lib/typescript/module/src/web/Button.d.ts +9 -0
  484. package/lib/typescript/module/src/web/Button.d.ts.map +1 -0
  485. package/lib/typescript/module/src/web/ButtonGroup.d.ts +11 -0
  486. package/lib/typescript/module/src/web/ButtonGroup.d.ts.map +1 -0
  487. package/lib/typescript/module/src/web/DatePicker.d.ts +14 -0
  488. package/lib/typescript/module/src/web/DatePicker.d.ts.map +1 -0
  489. package/lib/typescript/module/src/web/DateRangePicker.d.ts +11 -0
  490. package/lib/typescript/module/src/web/DateRangePicker.d.ts.map +1 -0
  491. package/lib/typescript/module/src/web/Dialog.d.ts +12 -0
  492. package/lib/typescript/module/src/web/Dialog.d.ts.map +1 -0
  493. package/lib/typescript/module/src/web/FloatingActionButton.d.ts +8 -0
  494. package/lib/typescript/module/src/web/FloatingActionButton.d.ts.map +1 -0
  495. package/lib/typescript/module/src/web/Icon.d.ts +12 -0
  496. package/lib/typescript/module/src/web/Icon.d.ts.map +1 -0
  497. package/lib/typescript/module/src/web/NativeTheme.d.ts +10 -0
  498. package/lib/typescript/module/src/web/NativeTheme.d.ts.map +1 -0
  499. package/lib/typescript/module/src/web/NavigationRail.d.ts +8 -0
  500. package/lib/typescript/module/src/web/NavigationRail.d.ts.map +1 -0
  501. package/lib/typescript/module/src/web/PlatformComponentsProvider.d.ts +10 -0
  502. package/lib/typescript/module/src/web/PlatformComponentsProvider.d.ts.map +1 -0
  503. package/lib/typescript/module/src/web/SegmentedControl.d.ts +8 -0
  504. package/lib/typescript/module/src/web/SegmentedControl.d.ts.map +1 -0
  505. package/lib/typescript/module/src/web/SelectionMenu.d.ts +10 -0
  506. package/lib/typescript/module/src/web/SelectionMenu.d.ts.map +1 -0
  507. package/lib/typescript/module/src/web/SplitButton.d.ts +9 -0
  508. package/lib/typescript/module/src/web/SplitButton.d.ts.map +1 -0
  509. package/lib/typescript/module/src/web/TabBar.d.ts +9 -0
  510. package/lib/typescript/module/src/web/TabBar.d.ts.map +1 -0
  511. package/lib/typescript/module/src/web/TextField.d.ts +9 -0
  512. package/lib/typescript/module/src/web/TextField.d.ts.map +1 -0
  513. package/lib/typescript/module/src/web/components.d.ts +17 -0
  514. package/lib/typescript/module/src/web/components.d.ts.map +1 -0
  515. package/lib/typescript/module/src/web/containers.d.ts +24 -0
  516. package/lib/typescript/module/src/web/containers.d.ts.map +1 -0
  517. package/lib/typescript/module/src/web/dateInput.d.ts +20 -0
  518. package/lib/typescript/module/src/web/dateInput.d.ts.map +1 -0
  519. package/lib/typescript/module/src/web/shared.d.ts +43 -0
  520. package/lib/typescript/module/src/web/shared.d.ts.map +1 -0
  521. package/lib/typescript/module/src/webComponents.d.ts +43 -0
  522. package/lib/typescript/module/src/webComponents.d.ts.map +1 -0
  523. package/package.json +32 -2
  524. package/plugin/build/index.d.ts +3 -2
  525. package/plugin/build/index.d.ts.map +1 -1
  526. package/react-native.config.js +3 -0
  527. package/shared/PCFloatingActionButtonComponentDescriptors-custom.h +22 -0
  528. package/shared/PCFloatingActionButtonShadowNode-custom.cpp +48 -0
  529. package/shared/PCFloatingActionButtonShadowNode-custom.h +54 -0
  530. package/shared/PCFloatingActionButtonState-custom.h +61 -0
  531. package/shared/PCNavigationRailComponentDescriptors-custom.h +47 -0
  532. package/shared/PCNavigationRailShadowNode-custom.h +42 -0
  533. package/shared/PCNavigationRailState-custom.h +62 -0
  534. package/shared/PCTabBarComponentDescriptors-custom.h +22 -0
  535. package/shared/PCTabBarShadowNode-custom.cpp +54 -0
  536. package/shared/PCTabBarShadowNode-custom.h +54 -0
  537. package/shared/PCTabBarState-custom.h +62 -0
  538. package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +3 -0
  539. package/src/Button.tsx +222 -7
  540. package/src/ButtonGroup.tsx +29 -11
  541. package/src/ButtonGroupNativeComponent.ts +74 -4
  542. package/src/ButtonNativeComponent.ts +119 -3
  543. package/src/ContextMenu.tsx +34 -81
  544. package/src/ContextMenuNativeComponent.ts +47 -49
  545. package/src/DatePicker.tsx +182 -4
  546. package/src/DatePickerNativeComponent.ts +19 -2
  547. package/src/FloatingActionButton.tsx +121 -0
  548. package/src/FloatingActionButtonNativeComponent.ts +58 -0
  549. package/src/FloatingToolbar.tsx +54 -3
  550. package/src/FloatingToolbarNativeComponent.ts +16 -0
  551. package/src/LiquidGlass.tsx +24 -1
  552. package/src/LiquidGlassContainer.tsx +42 -0
  553. package/src/LiquidGlassContainerNativeComponent.ts +17 -0
  554. package/src/LiquidGlassNativeComponent.ts +8 -0
  555. package/src/NavigationRail.tsx +203 -0
  556. package/src/NavigationRailNativeComponent.ts +107 -0
  557. package/src/PlatformComponentsProvider.tsx +15 -0
  558. package/src/SegmentedControl.tsx +31 -1
  559. package/src/SegmentedControlNativeComponent.ts +11 -0
  560. package/src/SelectionMenu.tsx +81 -6
  561. package/src/SelectionMenuNativeComponent.ts +26 -4
  562. package/src/SplitButton.tsx +198 -0
  563. package/src/TabBar.tsx +373 -0
  564. package/src/TabBarAccessoryNativeComponent.ts +19 -0
  565. package/src/TabBarNativeComponent.ts +145 -0
  566. package/src/TextField.tsx +428 -14
  567. package/src/TextFieldNativeComponent.ts +110 -4
  568. package/src/focusRegistry.ts +1 -0
  569. package/src/haptics.ts +31 -0
  570. package/src/icons.ts +28 -1
  571. package/src/index.tsx +7 -0
  572. package/src/index.web.tsx +51 -391
  573. package/src/jest.tsx +958 -0
  574. package/src/menuItems.ts +152 -0
  575. package/src/selectionIdentifiers.ts +17 -0
  576. package/src/submitBehavior.ts +16 -0
  577. package/src/tabItems.ts +113 -0
  578. package/src/web/Button.tsx +201 -0
  579. package/src/web/ButtonGroup.tsx +154 -0
  580. package/src/web/DatePicker.tsx +204 -0
  581. package/src/web/DateRangePicker.tsx +135 -0
  582. package/src/web/Dialog.tsx +54 -0
  583. package/src/web/FloatingActionButton.tsx +76 -0
  584. package/src/web/Icon.tsx +33 -0
  585. package/src/web/NativeTheme.ts +23 -0
  586. package/src/web/NavigationRail.tsx +148 -0
  587. package/src/web/PlatformComponentsProvider.tsx +48 -0
  588. package/src/web/SegmentedControl.tsx +127 -0
  589. package/src/web/SelectionMenu.tsx +149 -0
  590. package/src/web/SplitButton.tsx +32 -0
  591. package/src/web/TabBar.tsx +150 -0
  592. package/src/web/TextField.tsx +361 -0
  593. package/src/web/components.tsx +71 -0
  594. package/src/web/containers.tsx +130 -0
  595. package/src/web/dateInput.ts +137 -0
  596. package/src/web/shared.ts +176 -0
  597. package/src/webComponents.ts +45 -0
  598. package/android/src/main/java/com/platformcomponents/DateConstraints.kt +0 -83
@@ -1,16 +1,23 @@
1
1
  import UIKit
2
2
 
3
3
  /// A native button: `UIButton` with a `UIButton.Configuration` chosen by the
4
- /// variant, so it takes the system look of the iOS version it runs on.
4
+ /// variant, so it takes the system look of the iOS version it runs on. It can
5
+ /// be a toggle (`changesSelectionAsPrimaryAction`), open a `UIMenu` as its
6
+ /// primary action, and animate its SF Symbol.
5
7
  @objcMembers
6
8
  public final class PCButtonView: UIView {
7
9
  // MARK: - Props (set from ObjC++)
8
10
 
9
11
  public var label: String = "" {
10
- didSet { if oldValue != label { applyConfiguration() } }
12
+ didSet {
13
+ guard oldValue != label else { return }
14
+ applyConfiguration()
15
+ updateAccessibilityLabel()
16
+ }
11
17
  }
12
18
 
13
- /// "filled" | "tonal" | "outlined" | "text" | "elevated"
19
+ /// "filled" | "tonal" | "outlined" | "text" | "elevated" | "glass" |
20
+ /// "prominentGlass" | "clearGlass" | "prominentClearGlass"
14
21
  public var variant: String = "filled" {
15
22
  didSet { if oldValue != variant { applyConfiguration() } }
16
23
  }
@@ -25,11 +32,32 @@ public final class PCButtonView: UIView {
25
32
  didSet { if oldValue != shape { applyConfiguration() } }
26
33
  }
27
34
 
35
+ /// "leading" | "trailing" | "top" | "bottom"
36
+ public var iconPosition: String = "leading" {
37
+ didSet { if oldValue != iconPosition { applyConfiguration() } }
38
+ }
39
+
40
+ /// Corner radius in points; negative uses `shape`
41
+ public var cornerRadius: CGFloat = -1 {
42
+ didSet { if oldValue != cornerRadius { applyConfiguration() } }
43
+ }
44
+
28
45
  /// "enabled" | "disabled"
29
46
  public var interactivity: String = "enabled" {
30
47
  didSet { button.isEnabled = interactivity != "disabled" }
31
48
  }
32
49
 
50
+ /// Spinner in place of the label and icon; presses are ignored
51
+ public var loading: Bool = false {
52
+ didSet {
53
+ guard oldValue != loading else { return }
54
+ // Not isEnabled, so the button keeps its enabled colors
55
+ button.isUserInteractionEnabled = !loading
56
+ applyConfiguration()
57
+ updateAccessibilityLabel()
58
+ }
59
+ }
60
+
33
61
  /// Container color; nil keeps the configuration's color
34
62
  public var containerColor: UIColor? {
35
63
  didSet { applyConfiguration() }
@@ -40,19 +68,52 @@ public final class PCButtonView: UIView {
40
68
  didSet { applyConfiguration() }
41
69
  }
42
70
 
71
+ /// Container color while disabled; nil keeps the system disabled look
72
+ public var disabledContainerColor: UIColor? {
73
+ didSet { applyConfiguration() }
74
+ }
75
+
76
+ /// Label and icon color while disabled; nil keeps the system disabled look
77
+ public var disabledForegroundColor: UIColor? {
78
+ didSet { applyConfiguration() }
79
+ }
80
+
43
81
  /// Label font; nil keeps the configuration's font
44
82
  public var labelFont: UIFont? {
45
83
  didSet { applyConfiguration() }
46
84
  }
47
85
 
86
+ /// Cap on the default title font's Dynamic Type scaling; below 1 = no cap.
87
+ /// (A labelStyle font is capped when it is built, in PCButton.mm.)
88
+ public var maxFontSizeMultiplier: CGFloat = 0 {
89
+ didSet { if oldValue != maxFontSizeMultiplier { applyConfiguration() } }
90
+ }
91
+
48
92
  /// Screen-reader label; empty uses the label
49
93
  public var spokenLabel: String = "" {
50
- didSet { button.accessibilityLabel = spokenLabel.isEmpty ? nil : spokenLabel }
94
+ didSet { updateAccessibilityLabel() }
51
95
  }
52
96
 
97
+ /// ObjC++ sets this as an array of dictionaries: the flattened menu items
98
+ public var menuItems: [Any] = [] {
99
+ didSet {
100
+ items = PCMenuSupport.items(from: menuItems)
101
+ updateMenu()
102
+ }
103
+ }
104
+
105
+ /// The `haptics` prop: PCButton.mm plays it on a press (a toggle's
106
+ /// included), the menu handler on a pick
107
+ public let haptics = PCHaptics()
108
+
53
109
  // MARK: - Events back to ObjC++
54
110
 
55
111
  public var onPress: (() -> Void)?
112
+ /// A toggle was pressed; the state it asks for.
113
+ public var onSelectedChange: ((Bool) -> Void)?
114
+ public var onMenuSelect: ((String, String) -> Void)? // (id, title)
115
+ public var onMenuOpen: (() -> Void)?
116
+ public var onMenuClose: (() -> Void)?
56
117
 
57
118
  /// Called when content changed after layout (an icon finished loading),
58
119
  /// so the Fabric measurement can be refreshed.
@@ -60,13 +121,42 @@ public final class PCButtonView: UIView {
60
121
 
61
122
  // MARK: - Internal
62
123
 
63
- private let button = UIButton(type: .system)
124
+ /// Reports when its menu opens and closes (see PCMenuSupport.swift).
125
+ private let button = PCMenuButton(type: .system)
126
+
127
+ /// Hidden twin with the idle configuration, measured while loading so the
128
+ /// spinner keeps the button's size.
129
+ private let sizingButton = UIButton(type: .system)
130
+
131
+ /// The button whose size the view reports.
132
+ private var measuredButton: UIButton { loading ? sizingButton : button }
133
+
64
134
  private var icon = PCButtonSupport.Icon.none
65
135
  private var iconImage: UIImage?
66
136
 
67
137
  /// Bumped on every icon change so late image loads can't apply a stale icon.
68
138
  private var iconGeneration = 0
69
139
 
140
+ /// The enabled and selected states the current configuration was built for.
141
+ private var configuredEnabled = true
142
+ private var configuredSelected = false
143
+
144
+ private var hasDisabledColors: Bool {
145
+ disabledContainerColor != nil || disabledForegroundColor != nil
146
+ }
147
+
148
+ /// Whether the button is a toggle, and its controlled state.
149
+ private var isToggle = false
150
+ private var controlledSelected = false
151
+
152
+ private var items: [PCMenuItem] = []
153
+ private let menuImages = PCMenuImageState()
154
+ private var hasMenu: Bool { !items.isEmpty }
155
+
156
+ /// "" or an effect name; see `setSymbolEffect`.
157
+ private var symbolEffect = ""
158
+ private var symbolEffectTrigger = ""
159
+
70
160
  // MARK: - Init
71
161
 
72
162
  public override init(frame: CGRect) {
@@ -90,20 +180,147 @@ public final class PCButtonView: UIView {
90
180
  button.trailingAnchor.constraint(equalTo: trailingAnchor),
91
181
  ])
92
182
 
183
+ // Hidden, but in the hierarchy so it measures with the same traits
184
+ sizingButton.isHidden = true
185
+ sizingButton.isAccessibilityElement = false
186
+ addSubview(sizingButton)
187
+
188
+ // A menu is the primary action only while there is one
189
+ button.showsMenuAsPrimaryAction = false
190
+ button.onMenuOpen = { [weak self] in self?.onMenuOpen?() }
191
+ button.onMenuClose = { [weak self] in self?.onMenuClose?() }
192
+
93
193
  button.addTarget(self, action: #selector(pressed), for: .touchUpInside)
194
+ button.addTarget(self, action: #selector(touchedDown), for: .touchDown)
195
+ // Rebuild the configuration when isEnabled flips (custom disabled
196
+ // colors) or a toggle's isSelected does (see toggleVariant)
197
+ button.configurationUpdateHandler = { [weak self] button in
198
+ guard let self else { return }
199
+ let enabledChanged = self.hasDisabledColors && self.configuredEnabled != button.isEnabled
200
+ let selectedChanged = self.isToggle && self.configuredSelected != button.isSelected
201
+ guard enabledChanged || selectedChanged else { return }
202
+ button.configuration = self.makeConfiguration()
203
+ }
94
204
  applyConfiguration()
95
205
  }
96
206
 
97
207
  @objc private func pressed() {
208
+ guard !loading, !hasMenu else { return }
209
+ if isToggle {
210
+ // A press asks for the opposite of the controlled state. UIKit
211
+ // flips isSelected right away; syncSelected runs again once JS
212
+ // has answered, so the controlled value decides.
213
+ onSelectedChange?(!controlledSelected)
214
+ }
98
215
  onPress?()
99
216
  }
100
217
 
218
+ /// Readies the haptic for the press that is likely to follow.
219
+ @objc private func touchedDown() {
220
+ haptics.prepare(in: self)
221
+ }
222
+
223
+ // MARK: - Toggle
224
+
225
+ /// Applies the controlled toggle state: "" (not a toggle) | "true" |
226
+ /// "false". Called on every change of the prop and after every
227
+ /// `onSelectedChange`, so a state the parent didn't take goes back.
228
+ public func syncSelected(_ value: String) {
229
+ let wasToggle = isToggle
230
+ isToggle = !value.isEmpty
231
+ controlledSelected = value == "true"
232
+ updatePrimaryAction()
233
+ if button.isSelected != controlledSelected {
234
+ // The configuration follows in configurationUpdateHandler
235
+ button.isSelected = controlledSelected
236
+ } else if wasToggle != isToggle {
237
+ applyConfiguration()
238
+ }
239
+ }
240
+
241
+ /// A menu, when there is one, is the primary action; otherwise a toggle
242
+ /// flips its selection (UIKit's toggle button).
243
+ private func updatePrimaryAction() {
244
+ button.showsMenuAsPrimaryAction = hasMenu
245
+ button.changesSelectionAsPrimaryAction = isToggle && !hasMenu
246
+ }
247
+
248
+ // MARK: - Menu
249
+
250
+ private func updateMenu() {
251
+ menuImages.retain(icons: items.map(\.icon))
252
+ button.setMenu(hasMenu ? buildMenu() : nil)
253
+ updatePrimaryAction()
254
+ }
255
+
256
+ private func buildMenu() -> UIMenu {
257
+ PCMenuSupport.menu(
258
+ title: "",
259
+ items: items,
260
+ imageState: menuImages,
261
+ onImageLoaded: { [weak self] in self?.updateMenu() },
262
+ handler: { [weak self] item in
263
+ guard let self else { return }
264
+ self.haptics.perform(in: self, override: item.haptics)
265
+ self.onMenuSelect?(item.id, item.title)
266
+ }
267
+ )
268
+ }
269
+
270
+ // MARK: - Symbol effects
271
+
272
+ /// Animates the SF Symbol icon. With an empty `trigger` the effect repeats
273
+ /// until it is unset; otherwise it plays once whenever `trigger` changes
274
+ /// (not for the first value).
275
+ public func setSymbolEffect(_ effect: String, trigger: String) {
276
+ let modeChanged = effect != symbolEffect || trigger.isEmpty != symbolEffectTrigger.isEmpty
277
+ let triggerChanged = trigger != symbolEffectTrigger
278
+ symbolEffect = effect
279
+ symbolEffectTrigger = trigger
280
+ if modeChanged {
281
+ restartSymbolEffect()
282
+ } else if triggerChanged {
283
+ playSymbolEffectOnce()
284
+ }
285
+ }
286
+
287
+ /// The image view showing the SF Symbol, or nil for other icons.
288
+ private var symbolImageView: UIImageView? {
289
+ guard icon.type == "sfSymbol", !loading, iconImage != nil else { return nil }
290
+ // The configuration's image view is created on layout
291
+ button.layoutIfNeeded()
292
+ return button.imageView
293
+ }
294
+
295
+ /// Removes any effect, then starts the repeating one when there is no
296
+ /// trigger.
297
+ private func restartSymbolEffect() {
298
+ guard #available(iOS 17.0, *) else { return }
299
+ button.imageView?.removeAllSymbolEffects(animated: false)
300
+ guard symbolEffectTrigger.isEmpty, let imageView = symbolImageView else { return }
301
+ PCSymbolEffects.add(symbolEffect, to: imageView, repeating: true)
302
+ }
303
+
304
+ private func playSymbolEffectOnce() {
305
+ guard #available(iOS 17.0, *), let imageView = symbolImageView else { return }
306
+ PCSymbolEffects.add(symbolEffect, to: imageView, repeating: false)
307
+ }
308
+
309
+ /// The title is dropped while loading, so the label is kept explicitly.
310
+ private func updateAccessibilityLabel() {
311
+ if !spokenLabel.isEmpty {
312
+ button.accessibilityLabel = spokenLabel
313
+ } else {
314
+ button.accessibilityLabel = loading && !label.isEmpty ? label : nil
315
+ }
316
+ }
317
+
101
318
  // MARK: - Props handling
102
319
 
103
320
  /// Sets the icon from the flat spec fields. Images that are still loading
104
321
  /// apply once they arrive.
105
- public func setIcon(type: String, name: String, uri: String, scale: CGFloat, tinted: Bool) {
106
- let next = PCButtonSupport.Icon(type: type, name: name, uri: uri, scale: scale, tinted: tinted)
322
+ public func setIcon(type: String, name: String, request: String, uri: String, scale: CGFloat, tinted: Bool) {
323
+ let next = PCButtonSupport.Icon(type: type, name: name, uri: uri, scale: scale, tinted: tinted, request: request)
107
324
  guard next != icon else { return }
108
325
  icon = next
109
326
  iconGeneration += 1
@@ -119,8 +336,29 @@ public final class PCButtonView: UIView {
119
336
  }
120
337
 
121
338
  private func applyConfiguration() {
122
- button.configuration = PCButtonSupport.makeConfiguration(
123
- variant: variant,
339
+ button.configuration = makeConfiguration()
340
+ invalidateIntrinsicContentSize()
341
+ // A repeating effect starts over on the new image (and stops while
342
+ // loading, which drops the image).
343
+ if !symbolEffect.isEmpty && symbolEffectTrigger.isEmpty {
344
+ restartSymbolEffect()
345
+ }
346
+ }
347
+
348
+ private var imagePlacement: NSDirectionalRectEdge {
349
+ switch iconPosition {
350
+ case "trailing": return .trailing
351
+ case "top": return .top
352
+ case "bottom": return .bottom
353
+ default: return .leading
354
+ }
355
+ }
356
+
357
+ private func makeConfiguration() -> UIButton.Configuration {
358
+ configuredEnabled = button.isEnabled
359
+ configuredSelected = button.isSelected
360
+ var config = PCButtonSupport.makeConfiguration(
361
+ variant: isToggle ? PCButtonSupport.toggleVariant(variant, selected: configuredSelected) : variant,
124
362
  selected: false,
125
363
  size: size,
126
364
  shape: shape,
@@ -128,25 +366,70 @@ public final class PCButtonView: UIView {
128
366
  image: iconImage,
129
367
  containerColor: containerColor,
130
368
  foregroundColor: foregroundColor,
131
- font: labelFont
369
+ font: labelFont,
370
+ imagePlacement: imagePlacement,
371
+ cornerRadius: cornerRadius >= 0 ? cornerRadius : nil,
372
+ maxFontSizeMultiplier: maxFontSizeMultiplier,
373
+ traits: traitCollection
132
374
  )
133
- invalidateIntrinsicContentSize()
375
+ if !configuredEnabled {
376
+ applyDisabledColors(to: &config)
377
+ }
378
+ if loading {
379
+ // The idle configuration sizes the button; the spinner alone is
380
+ // centred in it, as the image's replacement.
381
+ sizingButton.configuration = config
382
+ config.title = nil
383
+ config.image = nil
384
+ config.imagePadding = 0
385
+ config.showsActivityIndicator = true
386
+ } else {
387
+ sizingButton.configuration = nil
388
+ }
389
+ return config
390
+ }
391
+
392
+ /// Replaces the system's disabled colors with the custom ones. The
393
+ /// transformers run last, after UIKit's own state handling.
394
+ private func applyDisabledColors(to config: inout UIButton.Configuration) {
395
+ if let color = disabledContainerColor {
396
+ config.background.backgroundColorTransformer = UIConfigurationColorTransformer { _ in color }
397
+ }
398
+ if let color = disabledForegroundColor {
399
+ let font = config.titleTextAttributesTransformer
400
+ config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
401
+ var outgoing = font?(incoming) ?? incoming
402
+ outgoing.foregroundColor = color
403
+ return outgoing
404
+ }
405
+ config.imageColorTransformer = UIConfigurationColorTransformer { _ in color }
406
+ }
407
+ }
408
+
409
+ // A capped title font is fixed, so it is rebuilt when the text size changes
410
+ public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
411
+ super.traitCollectionDidChange(previousTraitCollection)
412
+ guard maxFontSizeMultiplier >= 1,
413
+ previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory
414
+ else { return }
415
+ applyConfiguration()
416
+ onNeedsRemeasure?()
134
417
  }
135
418
 
136
419
  // MARK: - Sizing
137
420
 
138
421
  public override var intrinsicContentSize: CGSize {
139
- button.intrinsicContentSize
422
+ measuredButton.intrinsicContentSize
140
423
  }
141
424
 
142
425
  public override func sizeThatFits(_ size: CGSize) -> CGSize {
143
- button.sizeThatFits(size)
426
+ measuredButton.sizeThatFits(size)
144
427
  }
145
428
 
146
429
  /// Called by the measuring pipeline to get the size for Yoga layout: the
147
430
  /// button's natural size, or its height at the given width.
148
431
  @objc public func sizeForLayout(withConstrainedTo constrainedSize: CGSize) -> CGSize {
149
- let fitted = button.sizeThatFits(
432
+ let fitted = measuredButton.sizeThatFits(
150
433
  CGSize(width: constrainedSize.width > 0 ? constrainedSize.width : .greatestFiniteMagnitude,
151
434
  height: .greatestFiniteMagnitude)
152
435
  )
@@ -25,6 +25,22 @@ enum PCConstants {
25
25
  /// Vertical padding added to each menu row's text (top + bottom combined)
26
26
  static let popoverRowVerticalPadding: CGFloat = 16
27
27
 
28
+ /// Spacing between the selection checkmark and the row's label
29
+ static let popoverCheckmarkSpacing: CGFloat = 8
30
+
31
+ /// Symbol configuration of the selection checkmark (scales with Dynamic Type)
32
+ static var popoverCheckmarkConfiguration: UIImage.SymbolConfiguration {
33
+ UIImage.SymbolConfiguration(textStyle: .body, scale: .small)
34
+ .applying(UIImage.SymbolConfiguration(weight: .semibold))
35
+ }
36
+
37
+ /// Leading column reserved for the checkmark on every row when the menu has a
38
+ /// selection (like a system single-selection menu), checkmark width + spacing.
39
+ static var popoverCheckmarkColumnWidth: CGFloat {
40
+ let image = UIImage(systemName: "checkmark", withConfiguration: popoverCheckmarkConfiguration)
41
+ return ceil(image?.size.width ?? 17) + popoverCheckmarkSpacing
42
+ }
43
+
28
44
  /// Estimated single-line row height that respects the user's preferred
29
45
  /// content size. Used only as a table-view estimate; actual rows self-size.
30
46
  static var popoverRowHeight: CGFloat {
@@ -36,9 +52,14 @@ enum PCConstants {
36
52
  /// width, accounting for multi-line wrapping at the current Dynamic Type
37
53
  /// size. Mirrors the Auto Layout sizing of `PCGlassMenuCell` so the popover
38
54
  /// container can be sized to fit its content.
39
- static func popoverRowHeight(forLabel label: String, width: CGFloat) -> CGFloat {
55
+ static func popoverRowHeight(
56
+ forLabel label: String,
57
+ width: CGFloat,
58
+ reservesCheckmark: Bool = false
59
+ ) -> CGFloat {
40
60
  let bodyFont = UIFont.preferredFont(forTextStyle: .body)
41
- let textWidth = max(1, width - popoverRowHorizontalInset * 2)
61
+ let checkmarkReserve = reservesCheckmark ? popoverCheckmarkColumnWidth : 0
62
+ let textWidth = max(1, width - popoverRowHorizontalInset * 2 - checkmarkReserve)
42
63
  let bounding = (label as NSString).boundingRect(
43
64
  with: CGSize(width: textWidth, height: .greatestFiniteMagnitude),
44
65
  options: [.usesLineFragmentOrigin, .usesFontLeading],
@@ -16,110 +16,10 @@
16
16
  #import "PlatformComponents-Swift.h"
17
17
  #endif
18
18
 
19
- using namespace facebook::react;
20
-
21
- namespace {
22
- // Helper to convert subaction struct to NSDictionary
23
- static NSDictionary *SubactionToDict(const PCContextMenuActionsSubactionsStruct &action) {
24
- NSMutableDictionary *dict = [NSMutableDictionary new];
25
-
26
- dict[@"id"] = action.id.empty() ? @"" : [NSString stringWithUTF8String:action.id.c_str()];
27
- dict[@"title"] = action.title.empty() ? @"" : [NSString stringWithUTF8String:action.title.c_str()];
28
-
29
- if (!action.subtitle.empty()) {
30
- dict[@"subtitle"] = [NSString stringWithUTF8String:action.subtitle.c_str()];
31
- }
32
-
33
- if (!action.image.empty()) {
34
- dict[@"image"] = [NSString stringWithUTF8String:action.image.c_str()];
35
- }
36
-
37
- if (!action.imageColor.empty()) {
38
- dict[@"imageColor"] = [NSString stringWithUTF8String:action.imageColor.c_str()];
39
- }
40
-
41
- // Check if any attributes field is non-empty
42
- if (!action.attributes.destructive.empty() ||
43
- !action.attributes.disabled.empty() ||
44
- !action.attributes.hidden.empty()) {
45
- NSMutableDictionary *attrs = [NSMutableDictionary new];
46
- attrs[@"destructive"] = action.attributes.destructive.empty() ? @"false" :
47
- [NSString stringWithUTF8String:action.attributes.destructive.c_str()];
48
- attrs[@"disabled"] = action.attributes.disabled.empty() ? @"false" :
49
- [NSString stringWithUTF8String:action.attributes.disabled.c_str()];
50
- attrs[@"hidden"] = action.attributes.hidden.empty() ? @"false" :
51
- [NSString stringWithUTF8String:action.attributes.hidden.c_str()];
52
- dict[@"attributes"] = attrs;
53
- }
54
-
55
- if (!action.state.empty()) {
56
- dict[@"state"] = [NSString stringWithUTF8String:action.state.c_str()];
57
- }
58
-
59
- return dict;
60
- }
61
-
62
- // Helper to convert action struct to NSDictionary
63
- static NSDictionary *ActionToDict(const PCContextMenuActionsStruct &action) {
64
- NSMutableDictionary *dict = [NSMutableDictionary new];
65
-
66
- dict[@"id"] = action.id.empty() ? @"" : [NSString stringWithUTF8String:action.id.c_str()];
67
- dict[@"title"] = action.title.empty() ? @"" : [NSString stringWithUTF8String:action.title.c_str()];
68
-
69
- if (!action.subtitle.empty()) {
70
- dict[@"subtitle"] = [NSString stringWithUTF8String:action.subtitle.c_str()];
71
- }
72
-
73
- if (!action.image.empty()) {
74
- dict[@"image"] = [NSString stringWithUTF8String:action.image.c_str()];
75
- }
76
-
77
- if (!action.imageColor.empty()) {
78
- dict[@"imageColor"] = [NSString stringWithUTF8String:action.imageColor.c_str()];
79
- }
80
-
81
- // Check if any attributes field is non-empty
82
- if (!action.attributes.destructive.empty() ||
83
- !action.attributes.disabled.empty() ||
84
- !action.attributes.hidden.empty()) {
85
- NSMutableDictionary *attrs = [NSMutableDictionary new];
86
- attrs[@"destructive"] = action.attributes.destructive.empty() ? @"false" :
87
- [NSString stringWithUTF8String:action.attributes.destructive.c_str()];
88
- attrs[@"disabled"] = action.attributes.disabled.empty() ? @"false" :
89
- [NSString stringWithUTF8String:action.attributes.disabled.c_str()];
90
- attrs[@"hidden"] = action.attributes.hidden.empty() ? @"false" :
91
- [NSString stringWithUTF8String:action.attributes.hidden.c_str()];
92
- dict[@"attributes"] = attrs;
93
- }
19
+ #import "PCMenuItems.h"
94
20
 
95
- if (!action.state.empty()) {
96
- dict[@"state"] = [NSString stringWithUTF8String:action.state.c_str()];
97
- }
98
-
99
- // Convert subactions (vector, not optional)
100
- if (!action.subactions.empty()) {
101
- NSMutableArray *subs = [NSMutableArray new];
102
- for (const auto &sub : action.subactions) {
103
- [subs addObject:SubactionToDict(sub)];
104
- }
105
- dict[@"subactions"] = subs;
106
- }
107
-
108
- return dict;
109
- }
110
-
111
- static bool ActionsEqual(
112
- const std::vector<PCContextMenuActionsStruct> &a,
113
- const std::vector<PCContextMenuActionsStruct> &b) {
114
- if (a.size() != b.size()) return false;
115
- for (size_t i = 0; i < a.size(); i++) {
116
- if (a[i].id != b[i].id) return false;
117
- if (a[i].title != b[i].title) return false;
118
- // Simplified comparison - in production, compare all fields
119
- }
120
- return true;
121
- }
122
- } // namespace
21
+ using namespace facebook::react;
22
+ using namespace platformcomponents;
123
23
 
124
24
  @implementation PCContextMenu {
125
25
  PCContextMenuView *_view;
@@ -131,6 +31,12 @@ static bool ActionsEqual(
131
31
 
132
32
  - (instancetype)initWithFrame:(CGRect)frame {
133
33
  if (self = [super initWithFrame:frame]) {
34
+ // Fabric views seed _props with their own defaults: RCTViewComponentView
35
+ // asserts on it in debug builds of React Native core, and the first
36
+ // updateProps would otherwise read the base ViewProps as PCContextMenuProps.
37
+ static const auto defaultProps = std::make_shared<const PCContextMenuProps>();
38
+ _props = defaultProps;
39
+
134
40
  _view = [PCContextMenuView new];
135
41
  self.contentView = _view;
136
42
 
@@ -176,6 +82,18 @@ static bool ActionsEqual(
176
82
 
177
83
  eventEmitter->onMenuClose({});
178
84
  };
85
+
86
+ _view.onPreviewPress = ^{
87
+ __typeof(self) strongSelf = weakSelf;
88
+ if (!strongSelf) return;
89
+
90
+ auto eventEmitter =
91
+ std::static_pointer_cast<const PCContextMenuEventEmitter>(
92
+ strongSelf->_eventEmitter);
93
+ if (!eventEmitter) return;
94
+
95
+ eventEmitter->onPreviewPress({});
96
+ };
179
97
  }
180
98
  return self;
181
99
  }
@@ -196,13 +114,9 @@ static bool ActionsEqual(
196
114
  }
197
115
  }
198
116
 
199
- // actions
200
- if (!prevProps || !ActionsEqual(newProps.actions, prevProps->actions)) {
201
- NSMutableArray *arr = [NSMutableArray new];
202
- for (const auto &action : newProps.actions) {
203
- [arr addObject:ActionToDict(action)];
204
- }
205
- _view.actions = arr;
117
+ // actions: the flattened menu items
118
+ if (!prevProps || !PCMenuItemsEqual(newProps.actions, prevProps->actions)) {
119
+ _view.actions = PCMenuItemsToArray(newProps.actions);
206
120
  }
207
121
 
208
122
  // interactivity: "enabled" | "disabled"
@@ -225,6 +139,10 @@ static bool ActionsEqual(
225
139
  }
226
140
  }
227
141
 
142
+ if (!prevProps || newProps.haptics != prevProps->haptics) {
143
+ _view.haptics.kind = [NSString stringWithUTF8String:newProps.haptics.c_str()];
144
+ }
145
+
228
146
  // iOS-specific props
229
147
  const auto &newIOS = newProps.ios;
230
148
  const auto &oldIOS = prevProps ? prevProps->ios : PCContextMenuIosStruct{};