react-native-platform-components 1.4.0 → 1.6.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 (600) 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.cjs +79 -6
  525. package/plugin/build/index.d.ts +27 -2
  526. package/plugin/build/index.d.ts.map +1 -1
  527. package/plugin/tsconfig.json +2 -1
  528. package/react-native.config.js +3 -0
  529. package/shared/PCFloatingActionButtonComponentDescriptors-custom.h +22 -0
  530. package/shared/PCFloatingActionButtonShadowNode-custom.cpp +48 -0
  531. package/shared/PCFloatingActionButtonShadowNode-custom.h +54 -0
  532. package/shared/PCFloatingActionButtonState-custom.h +61 -0
  533. package/shared/PCNavigationRailComponentDescriptors-custom.h +47 -0
  534. package/shared/PCNavigationRailShadowNode-custom.h +42 -0
  535. package/shared/PCNavigationRailState-custom.h +62 -0
  536. package/shared/PCTabBarComponentDescriptors-custom.h +22 -0
  537. package/shared/PCTabBarShadowNode-custom.cpp +54 -0
  538. package/shared/PCTabBarShadowNode-custom.h +54 -0
  539. package/shared/PCTabBarState-custom.h +62 -0
  540. package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +3 -0
  541. package/src/Button.tsx +222 -7
  542. package/src/ButtonGroup.tsx +29 -11
  543. package/src/ButtonGroupNativeComponent.ts +74 -4
  544. package/src/ButtonNativeComponent.ts +119 -3
  545. package/src/ContextMenu.tsx +34 -81
  546. package/src/ContextMenuNativeComponent.ts +47 -49
  547. package/src/DatePicker.tsx +182 -4
  548. package/src/DatePickerNativeComponent.ts +19 -2
  549. package/src/FloatingActionButton.tsx +121 -0
  550. package/src/FloatingActionButtonNativeComponent.ts +58 -0
  551. package/src/FloatingToolbar.tsx +54 -3
  552. package/src/FloatingToolbarNativeComponent.ts +16 -0
  553. package/src/LiquidGlass.tsx +24 -1
  554. package/src/LiquidGlassContainer.tsx +42 -0
  555. package/src/LiquidGlassContainerNativeComponent.ts +17 -0
  556. package/src/LiquidGlassNativeComponent.ts +8 -0
  557. package/src/NavigationRail.tsx +203 -0
  558. package/src/NavigationRailNativeComponent.ts +107 -0
  559. package/src/PlatformComponentsProvider.tsx +15 -0
  560. package/src/SegmentedControl.tsx +31 -1
  561. package/src/SegmentedControlNativeComponent.ts +11 -0
  562. package/src/SelectionMenu.tsx +81 -6
  563. package/src/SelectionMenuNativeComponent.ts +26 -4
  564. package/src/SplitButton.tsx +198 -0
  565. package/src/TabBar.tsx +373 -0
  566. package/src/TabBarAccessoryNativeComponent.ts +19 -0
  567. package/src/TabBarNativeComponent.ts +145 -0
  568. package/src/TextField.tsx +428 -14
  569. package/src/TextFieldNativeComponent.ts +110 -4
  570. package/src/focusRegistry.ts +1 -0
  571. package/src/haptics.ts +31 -0
  572. package/src/icons.ts +28 -1
  573. package/src/index.tsx +7 -0
  574. package/src/index.web.tsx +51 -391
  575. package/src/jest.tsx +958 -0
  576. package/src/menuItems.ts +152 -0
  577. package/src/selectionIdentifiers.ts +17 -0
  578. package/src/submitBehavior.ts +16 -0
  579. package/src/tabItems.ts +113 -0
  580. package/src/web/Button.tsx +201 -0
  581. package/src/web/ButtonGroup.tsx +154 -0
  582. package/src/web/DatePicker.tsx +204 -0
  583. package/src/web/DateRangePicker.tsx +135 -0
  584. package/src/web/Dialog.tsx +54 -0
  585. package/src/web/FloatingActionButton.tsx +76 -0
  586. package/src/web/Icon.tsx +33 -0
  587. package/src/web/NativeTheme.ts +23 -0
  588. package/src/web/NavigationRail.tsx +148 -0
  589. package/src/web/PlatformComponentsProvider.tsx +48 -0
  590. package/src/web/SegmentedControl.tsx +127 -0
  591. package/src/web/SelectionMenu.tsx +149 -0
  592. package/src/web/SplitButton.tsx +32 -0
  593. package/src/web/TabBar.tsx +150 -0
  594. package/src/web/TextField.tsx +361 -0
  595. package/src/web/components.tsx +71 -0
  596. package/src/web/containers.tsx +130 -0
  597. package/src/web/dateInput.ts +137 -0
  598. package/src/web/shared.ts +176 -0
  599. package/src/webComponents.ts +45 -0
  600. package/android/src/main/java/com/platformcomponents/DateConstraints.kt +0 -83
@@ -0,0 +1,280 @@
1
+ package com.platformcomponents
2
+
3
+ import android.content.Context
4
+ import android.graphics.Rect
5
+ import android.graphics.drawable.BitmapDrawable
6
+ import android.graphics.drawable.Drawable
7
+ import android.graphics.drawable.DrawableWrapper
8
+ import android.text.SpannableString
9
+ import android.text.Spanned
10
+ import android.text.style.ForegroundColorSpan
11
+ import android.util.Log
12
+ import android.util.TypedValue
13
+ import android.view.Menu
14
+ import android.view.MenuItem
15
+ import androidx.appcompat.R as AppCompatR
16
+ import androidx.core.content.ContextCompat
17
+ import androidx.core.graphics.drawable.DrawableCompat
18
+ import androidx.core.view.MenuCompat
19
+ import com.facebook.react.bridge.ReadableArray
20
+ import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper
21
+ import com.platformcomponents.PCButtonSupport.doubleOr
22
+ import com.platformcomponents.PCButtonSupport.stringOr
23
+ import kotlin.math.roundToInt
24
+
25
+ /**
26
+ * Builds Android menus from flattened menu items (src/menuItems.ts): inline
27
+ * sections become menu groups with dividers, and items get submenus, icons
28
+ * (drawables and React Native image sources), the destructive color, the
29
+ * enabled state and a check mark. Shared by the components that show a
30
+ * PopupMenu.
31
+ */
32
+ object PCMenuSupport {
33
+ private const val TAG = "PCMenuSupport"
34
+
35
+ // Material 3 baseline error color, used when the theme has no colorError.
36
+ private const val FALLBACK_ERROR_COLOR = 0xFFB3261E.toInt()
37
+
38
+ // Material menu and list icons are 24dp
39
+ private const val ICON_SIZE_DP = 24
40
+
41
+ data class Item(
42
+ /** Position in the flattened list; also the MenuItem id */
43
+ val index: Int,
44
+ val id: String,
45
+ val title: String,
46
+ val subtitle: String,
47
+ /** Index of the parent submenu or section; -1 at the top level */
48
+ val parent: Int,
49
+ /** "action" | "menu" | "section" */
50
+ val kind: String,
51
+ val icon: PCButtonSupport.Icon,
52
+ val imageColor: String,
53
+ val destructive: Boolean,
54
+ val disabled: Boolean,
55
+ /** iOS only; Android popups close on every press */
56
+ val keepsMenuPresented: Boolean,
57
+ /** "" | "off" | "on" | "mixed" */
58
+ val state: String,
59
+ /** The item's own `haptics`; "" = the component's */
60
+ val haptics: String = ""
61
+ ) {
62
+ val isAction: Boolean get() = kind != "menu" && kind != "section"
63
+ }
64
+
65
+ /** Reads the flattened items from the `actions` prop. */
66
+ fun parseItems(array: ReadableArray?): List<Item> {
67
+ if (array == null) return emptyList()
68
+ val out = ArrayList<Item>(array.size())
69
+ for (i in 0 until array.size()) {
70
+ val map = array.getMap(i) ?: continue
71
+ out.add(
72
+ Item(
73
+ index = out.size,
74
+ id = map.stringOr("id", ""),
75
+ title = map.stringOr("title", ""),
76
+ subtitle = map.stringOr("subtitle", ""),
77
+ parent = map.doubleOr("parent", -1.0).toInt(),
78
+ kind = map.stringOr("kind", "action"),
79
+ icon = PCButtonSupport.parseIcon(map),
80
+ imageColor = map.stringOr("imageColor", ""),
81
+ destructive = map.stringOr("destructive", "false") == "true",
82
+ disabled = map.stringOr("disabled", "false") == "true",
83
+ keepsMenuPresented = map.stringOr("keepsMenuPresented", "false") == "true",
84
+ state = map.stringOr("state", ""),
85
+ haptics = map.stringOr("haptics", "")
86
+ )
87
+ )
88
+ }
89
+ return out
90
+ }
91
+
92
+ /**
93
+ * Adds [items] to [menu]. Each MenuItem's id is its item's index, so
94
+ * [itemFor] finds the item behind a click. Image icons that load in the
95
+ * background are set when they arrive, while [isCurrent] holds. Returns
96
+ * whether any item has an icon (for `PopupMenu.setForceShowIcon`).
97
+ */
98
+ fun populate(
99
+ context: Context,
100
+ menu: Menu,
101
+ items: List<Item>,
102
+ isCurrent: () -> Boolean = { true }
103
+ ): Boolean {
104
+ val children = items.groupBy { it.parent }
105
+ var nextGroupId = 1
106
+ var hasIcons = false
107
+
108
+ fun add(target: Menu, parent: Int) {
109
+ val list = children[parent] ?: return
110
+ // Dividers are drawn where the group id changes: each section gets its
111
+ // own group, and so does each run of items between sections.
112
+ var groupId = nextGroupId++
113
+ var order = 0
114
+ var sectionsInMenu = false
115
+
116
+ fun addItem(item: Item, group: Int) {
117
+ when (item.kind) {
118
+ "menu" -> {
119
+ if (children[item.index].isNullOrEmpty()) return
120
+ val subMenu = target.addSubMenu(group, item.index, order++, item.title)
121
+ subMenu.item.isEnabled = !item.disabled
122
+ if (applyIcon(context, subMenu.item, item, isCurrent)) hasIcons = true
123
+ add(subMenu, item.index)
124
+ }
125
+ else -> {
126
+ val menuItem = target.add(group, item.index, order++, title(context, item))
127
+ menuItem.isEnabled = !item.disabled
128
+ if (applyIcon(context, menuItem, item, isCurrent)) hasIcons = true
129
+ // Android has no mixed state: "mixed" shows checked
130
+ if (item.state == "on" || item.state == "mixed") {
131
+ menuItem.isCheckable = true
132
+ menuItem.isChecked = true
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ // A section's items; sections nested in it add their items to the same group
139
+ fun sectionItems(section: Item): List<Item> =
140
+ children[section.index].orEmpty().flatMap {
141
+ if (it.kind == "section") sectionItems(it) else listOf(it)
142
+ }
143
+
144
+ for (item in list) {
145
+ if (item.kind == "section") {
146
+ val sectionItems = sectionItems(item)
147
+ if (sectionItems.isEmpty()) continue
148
+ sectionsInMenu = true
149
+ val sectionGroup = nextGroupId++
150
+ sectionItems.forEach { addItem(it, sectionGroup) }
151
+ // Items after the section start a new group
152
+ groupId = nextGroupId++
153
+ } else {
154
+ addItem(item, groupId)
155
+ }
156
+ }
157
+
158
+ if (sectionsInMenu) MenuCompat.setGroupDividerEnabled(target, true)
159
+ }
160
+
161
+ add(menu, -1)
162
+ return hasIcons
163
+ }
164
+
165
+ /** The item behind a clicked MenuItem. */
166
+ fun itemFor(menuItem: MenuItem, items: List<Item>): Item? = items.getOrNull(menuItem.itemId)
167
+
168
+ /** Destructive titles are drawn in the theme's error color. */
169
+ private fun title(context: Context, item: Item): CharSequence {
170
+ if (!item.destructive) return item.title
171
+ return SpannableString(item.title).apply {
172
+ setSpan(ForegroundColorSpan(errorColor(context)), 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Sets the item's icon; returns whether it has one. An explicit imageColor
178
+ * tints it; destructive icons otherwise take the error color.
179
+ */
180
+ private fun applyIcon(
181
+ context: Context,
182
+ menuItem: MenuItem,
183
+ item: Item,
184
+ isCurrent: () -> Boolean
185
+ ): Boolean {
186
+ if (!item.icon.isPresent) return false
187
+ loadIcon(context, item.icon) { drawable ->
188
+ if (drawable == null || !isCurrent()) return@loadIcon
189
+ val color = when {
190
+ item.imageColor.isNotEmpty() -> ColorParser.parse(item.imageColor)
191
+ item.destructive -> errorColor(context)
192
+ else -> null
193
+ }
194
+ menuItem.icon = if (color != null) tint(drawable, color) else drawable
195
+ }
196
+ return true
197
+ }
198
+
199
+ /**
200
+ * Resolves an icon to a drawable. Drawable names and release-bundled assets
201
+ * (drawable resources) resolve right away; other image URIs load in the
202
+ * background and arrive on the main thread. Image sources sit in a 24dp
203
+ * box, and those drawn as templates take the theme's icon color
204
+ * (`?attr/colorControlNormal`, as Material icons do); drawables keep their
205
+ * own size and tint.
206
+ */
207
+ fun loadIcon(context: Context, icon: PCButtonSupport.Icon, onLoaded: (Drawable?) -> Unit) {
208
+ fun imageIcon(drawable: Drawable): Drawable {
209
+ val size = (ICON_SIZE_DP * context.resources.displayMetrics.density).roundToInt()
210
+ val color = if (icon.tinted) themeColor(context, AppCompatR.attr.colorControlNormal) else null
211
+ return IconBox(if (color != null) tint(drawable, color) else drawable, size)
212
+ }
213
+ when (icon.type) {
214
+ "drawable" -> onLoaded(drawableByName(context, icon.name))
215
+ "image" -> {
216
+ val uri = icon.uri
217
+ if (!uri.contains(':')) {
218
+ onLoaded(ResourceDrawableIdHelper.instance.getResourceDrawable(context, uri)?.let(::imageIcon))
219
+ } else {
220
+ PCImageLoader.load(context, uri, icon.scale, icon.request) { bitmap ->
221
+ onLoaded(bitmap?.let { imageIcon(BitmapDrawable(context.resources, it)) })
222
+ }
223
+ }
224
+ }
225
+ else -> onLoaded(null)
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Keeps an image source in the 24dp box of Material menu icons, centered
231
+ * and scaled down when larger, so its row lines up with the drawable icons.
232
+ */
233
+ private class IconBox(drawable: Drawable, private val size: Int) : DrawableWrapper(drawable) {
234
+ override fun getIntrinsicWidth(): Int = size
235
+ override fun getIntrinsicHeight(): Int = size
236
+
237
+ override fun onBoundsChange(bounds: Rect) {
238
+ val inner = drawable ?: return
239
+ val w = inner.intrinsicWidth.takeIf { it > 0 } ?: bounds.width()
240
+ val h = inner.intrinsicHeight.takeIf { it > 0 } ?: bounds.height()
241
+ val scale = minOf(1f, bounds.width().toFloat() / w, bounds.height().toFloat() / h)
242
+ val width = (w * scale).roundToInt()
243
+ val height = (h * scale).roundToInt()
244
+ val left = bounds.left + (bounds.width() - width) / 2
245
+ val top = bounds.top + (bounds.height() - height) / 2
246
+ inner.setBounds(left, top, left + width, top + height)
247
+ }
248
+ }
249
+
250
+ private fun tint(drawable: Drawable, color: Int): Drawable {
251
+ val wrapped = DrawableCompat.wrap(drawable.mutate())
252
+ DrawableCompat.setTint(wrapped, color)
253
+ return wrapped
254
+ }
255
+
256
+ /** A drawable resource by name, also trying the `ic_` prefix. */
257
+ private fun drawableByName(context: Context, name: String): Drawable? {
258
+ if (name.isEmpty()) return null
259
+ for (candidate in listOf(name, "ic_$name")) {
260
+ val id = context.resources.getIdentifier(candidate, "drawable", context.packageName)
261
+ if (id != 0) return ContextCompat.getDrawable(context, id)
262
+ }
263
+ Log.d(TAG, "Drawable not found: $name")
264
+ return null
265
+ }
266
+
267
+ /** The theme's ?attr/colorError, falling back to the Material 3 error red. */
268
+ fun errorColor(context: Context): Int =
269
+ themeColor(context, AppCompatR.attr.colorError) ?: FALLBACK_ERROR_COLOR
270
+
271
+ fun themeColor(context: Context, attr: Int): Int? {
272
+ val value = TypedValue()
273
+ if (!context.theme.resolveAttribute(attr, value, true)) return null
274
+ return if (value.resourceId != 0) {
275
+ ContextCompat.getColor(context, value.resourceId)
276
+ } else {
277
+ value.data
278
+ }
279
+ }
280
+ }
@@ -0,0 +1,332 @@
1
+ package com.platformcomponents
2
+
3
+ import android.content.Context
4
+ import android.content.res.ColorStateList
5
+ import android.graphics.drawable.BitmapDrawable
6
+ import android.graphics.drawable.Drawable
7
+ import android.graphics.drawable.StateListDrawable
8
+ import android.util.TypedValue
9
+ import android.view.Menu
10
+ import android.view.View
11
+ import android.view.ViewGroup
12
+ import android.widget.TextView
13
+ import androidx.core.content.ContextCompat
14
+ import androidx.core.view.MenuItemCompat
15
+ import com.facebook.react.bridge.ReadableArray
16
+ import com.facebook.react.bridge.ReadableMap
17
+ import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper
18
+ import com.facebook.react.views.text.ReactTypefaceUtils
19
+ import com.google.android.material.navigation.NavigationBarView
20
+ import com.google.android.material.shape.RelativeCornerSize
21
+ import com.google.android.material.shape.ShapeAppearanceModel
22
+ import com.platformcomponents.PCButtonSupport.doubleOr
23
+ import com.platformcomponents.PCButtonSupport.stringOr
24
+ import kotlin.math.roundToInt
25
+
26
+ /**
27
+ * Tabs on a Material navigation bar (NavigationBarView, the base of
28
+ * BottomNavigationView and NavigationRailView): the item model as the specs
29
+ * send it, and building the menu, icons, badges, colors, active indicator,
30
+ * test ids and label fonts.
31
+ */
32
+ object PCNavigationBarSupport {
33
+
34
+ data class Item(
35
+ val label: String,
36
+ val value: String,
37
+ val disabled: Boolean,
38
+ val icon: PCButtonSupport.Icon,
39
+ val selectedIcon: PCButtonSupport.Icon,
40
+ /** "" = no badge, " " = a dot, anything else is the badge text */
41
+ val badge: String,
42
+ val accessibilityLabel: String,
43
+ val testID: String,
44
+ /** "" | "search": a search tab without an icon gets a search icon */
45
+ val role: String = ""
46
+ )
47
+
48
+ /** Label font and font scale cap; empty / 0 = the platform default. */
49
+ data class LabelFont(
50
+ val family: String = "",
51
+ val size: Float = 0f,
52
+ val weight: String = "",
53
+ val style: String = "",
54
+ val maxFontSizeMultiplier: Float = 0f
55
+ )
56
+
57
+ /** The active indicator; 0 = the Material default size. */
58
+ data class Indicator(
59
+ val enabled: Boolean = true,
60
+ /** "" | "pill" | "circle" | "rounded" (cornerRadius) */
61
+ val shape: String = "",
62
+ val cornerRadius: Float = 0f,
63
+ val width: Float = 0f,
64
+ val height: Float = 0f
65
+ )
66
+
67
+ /** Menu item id of the tab at [index]; 0 means "no id" to the menu. */
68
+ fun itemId(index: Int) = index + 1
69
+
70
+ // items: [{label, value, disabled, icon…, selectedIcon…, badge, accessibilityLabel, testID, role}]
71
+ fun parseItems(value: ReadableArray?): List<Item> {
72
+ val out = ArrayList<Item>()
73
+ if (value == null) return out
74
+ for (i in 0 until value.size()) {
75
+ val m = value.getMap(i) ?: continue
76
+ out.add(
77
+ Item(
78
+ label = m.stringOr("label", ""),
79
+ value = m.stringOr("value", ""),
80
+ disabled = m.stringOr("disabled", "enabled") == "disabled",
81
+ icon = m.icon(""),
82
+ selectedIcon = m.icon("selected"),
83
+ badge = m.stringOr("badge", ""),
84
+ accessibilityLabel = m.stringOr("accessibilityLabel", ""),
85
+ testID = m.stringOr("testID", ""),
86
+ role = m.stringOr("role", "")
87
+ )
88
+ )
89
+ }
90
+ return out
91
+ }
92
+
93
+ private fun ReadableMap.icon(prefix: String): PCButtonSupport.Icon {
94
+ fun key(name: String) = if (prefix.isEmpty()) name else prefix + name.replaceFirstChar { it.uppercase() }
95
+ val scale = doubleOr(key("iconScale"), 1.0)
96
+ return PCButtonSupport.Icon(
97
+ type = stringOr(key("iconType"), ""),
98
+ name = stringOr(key("iconName"), ""),
99
+ uri = stringOr(key("iconUri"), ""),
100
+ scale = if (scale > 0) scale.toFloat() else 1f,
101
+ tinted = stringOr(key("iconTinted"), "true") != "false",
102
+ request = stringOr(key("iconRequest"), "")
103
+ )
104
+ }
105
+
106
+ fun labelVisibilityMode(value: String): Int = when (value) {
107
+ "labeled" -> NavigationBarView.LABEL_VISIBILITY_LABELED
108
+ "selected" -> NavigationBarView.LABEL_VISIBILITY_SELECTED
109
+ "unlabeled" -> NavigationBarView.LABEL_VISIBILITY_UNLABELED
110
+ else -> NavigationBarView.LABEL_VISIBILITY_AUTO
111
+ }
112
+
113
+ /**
114
+ * Icons above the labels ("vertical"), or beside them ("horizontal",
115
+ * Material 3 Expressive), centered in the bar; "auto" is horizontal from
116
+ * 600dp, the medium window width.
117
+ */
118
+ fun applyItemLayout(bar: NavigationBarView, layout: String, widthPx: Int) {
119
+ val horizontal = when (layout) {
120
+ "horizontal" -> true
121
+ "auto" -> widthPx / bar.resources.displayMetrics.density >= 600f
122
+ else -> false
123
+ }
124
+ val iconGravity =
125
+ if (horizontal) NavigationBarView.ITEM_ICON_GRAVITY_START else NavigationBarView.ITEM_ICON_GRAVITY_TOP
126
+ if (bar.itemIconGravity == iconGravity) return
127
+ bar.itemIconGravity = iconGravity
128
+ bar.itemGravity =
129
+ if (horizontal) NavigationBarView.ITEM_GRAVITY_CENTER else NavigationBarView.ITEM_GRAVITY_TOP_CENTER
130
+ }
131
+
132
+ /**
133
+ * Adds the tabs to the bar's menu, as many as it takes, with their icons.
134
+ * Icons that load in the background are applied while [isCurrent] holds,
135
+ * then [onIconLoaded] runs. Call after [applyColors] so each icon receives
136
+ * the final state colors before the bar-wide tint is disabled.
137
+ */
138
+ fun populateMenu(
139
+ bar: NavigationBarView,
140
+ items: List<Item>,
141
+ isCurrent: () -> Boolean,
142
+ onIconLoaded: () -> Unit
143
+ ) {
144
+ val menu = bar.menu
145
+ // Material's bar-wide tint overrides an image's original colors. Apply the
146
+ // same state list to each opted-in icon, including its selected variant.
147
+ // https://developer.android.com/reference/com/google/android/material/navigation/NavigationBarView#setItemIconTintList(android.content.res.ColorStateList)
148
+ val iconTint = bar.itemIconTintList
149
+ bar.itemIconTintList = null
150
+ val count = minOf(items.size, bar.maxItemCount)
151
+ for (index in 0 until count) {
152
+ val tab = items[index]
153
+ val item = menu.add(Menu.NONE, itemId(index), index, tab.label)
154
+ item.isEnabled = !tab.disabled
155
+ MenuItemCompat.setContentDescription(item, tab.accessibilityLabel.ifEmpty { null })
156
+ loadItemIcon(bar.context, tab, iconTint, isCurrent) { drawable ->
157
+ item.icon = drawable
158
+ onIconLoaded()
159
+ }
160
+ }
161
+ }
162
+
163
+ /** Colors over the theme's, read from the fresh bar for the states left unset. */
164
+ fun applyColors(
165
+ bar: NavigationBarView,
166
+ active: Int?,
167
+ inactive: Int?,
168
+ indicator: Int?,
169
+ ripple: Int?,
170
+ background: Int?
171
+ ) {
172
+ val checked = intArrayOf(android.R.attr.state_checked)
173
+ val disabled = intArrayOf(-android.R.attr.state_enabled)
174
+ if (active != null || inactive != null) {
175
+ fun tint(theme: ColorStateList?): ColorStateList {
176
+ val base = theme ?: ColorStateList.valueOf(0xFF49454F.toInt())
177
+ return ColorStateList(
178
+ arrayOf(disabled, checked, intArrayOf()),
179
+ intArrayOf(
180
+ base.getColorForState(disabled, base.defaultColor),
181
+ active ?: base.getColorForState(checked, base.defaultColor),
182
+ inactive ?: base.defaultColor
183
+ )
184
+ )
185
+ }
186
+ bar.itemIconTintList = tint(bar.itemIconTintList)
187
+ bar.itemTextColor = tint(bar.itemTextColor)
188
+ }
189
+ indicator?.let { bar.itemActiveIndicatorColor = ColorStateList.valueOf(it) }
190
+ ripple?.let { bar.itemRippleColor = ColorStateList.valueOf(it) }
191
+ background?.let { bar.setBackgroundColor(it) }
192
+ }
193
+
194
+ /** The active indicator's visibility, size and shape. */
195
+ fun applyIndicator(bar: NavigationBarView, indicator: Indicator) {
196
+ bar.isItemActiveIndicatorEnabled = indicator.enabled
197
+ val density = bar.resources.displayMetrics.density
198
+ fun px(dp: Float) = (dp * density).roundToInt()
199
+ if (indicator.height > 0) {
200
+ bar.itemActiveIndicatorHeight = px(indicator.height)
201
+ bar.itemActiveIndicatorExpandedHeight = px(indicator.height)
202
+ }
203
+ // Horizontal tabs keep an indicator that wraps the icon and label
204
+ when {
205
+ indicator.shape == "circle" -> bar.itemActiveIndicatorWidth = bar.itemActiveIndicatorHeight
206
+ indicator.width > 0 -> bar.itemActiveIndicatorWidth = px(indicator.width)
207
+ }
208
+ val shape = when (indicator.shape) {
209
+ "pill", "circle" -> ShapeAppearanceModel.builder().setAllCornerSizes(RelativeCornerSize(0.5f)).build()
210
+ "rounded" -> ShapeAppearanceModel.builder().setAllCornerSizes(indicator.cornerRadius * density).build()
211
+ else -> null
212
+ }
213
+ shape?.let { bar.itemActiveIndicatorShapeAppearance = it }
214
+ }
215
+
216
+ /** Material badges: a number, text, or a dot. */
217
+ fun applyBadges(bar: NavigationBarView, items: List<Item>, background: Int?, text: Int?) {
218
+ val count = minOf(items.size, bar.maxItemCount)
219
+ for (index in 0 until count) {
220
+ val tab = items[index]
221
+ val id = itemId(index)
222
+ if (tab.badge.isEmpty()) {
223
+ bar.removeBadge(id)
224
+ continue
225
+ }
226
+ val badge = bar.getOrCreateBadge(id)
227
+ badge.clearNumber()
228
+ badge.clearText()
229
+ val number = tab.badge.trim().toIntOrNull()
230
+ when {
231
+ tab.badge == " " -> Unit // a dot
232
+ number != null && number >= 0 -> badge.number = number
233
+ else -> badge.text = tab.badge
234
+ }
235
+ background?.let { badge.backgroundColor = it }
236
+ text?.let { badge.badgeTextColor = it }
237
+ badge.isVisible = true
238
+ }
239
+ }
240
+
241
+ /**
242
+ * testIDs on the tab views (Detox matches the view tag), and the label font
243
+ * and font scale cap on their labels. Material creates the label views as
244
+ * tabs are added; call again after a layout to style new ones.
245
+ */
246
+ fun applyTestIDsAndFonts(bar: NavigationBarView, items: List<Item>, font: LabelFont) {
247
+ // In the menu view only: a rail's header holds React views, whose ids
248
+ // (React tags) can equal a tab's id
249
+ val menuView = bar.menuView as? ViewGroup ?: return
250
+ val count = minOf(items.size, bar.maxItemCount)
251
+ for (index in 0 until count) {
252
+ val itemView = menuView.findViewById<View>(itemId(index)) ?: continue
253
+ itemView.tag = items[index].testID.ifEmpty { null }
254
+ styleLabels(itemView, font)
255
+ }
256
+ }
257
+
258
+ private fun styleLabels(view: View, font: LabelFont) {
259
+ if (view is TextView) {
260
+ if (font.size > 0) view.setTextSize(TypedValue.COMPLEX_UNIT_SP, font.size)
261
+ if (font.family.isNotEmpty() || font.weight.isNotEmpty() || font.style.isNotEmpty()) {
262
+ view.typeface = ReactTypefaceUtils.applyStyles(
263
+ view.typeface,
264
+ ReactTypefaceUtils.parseFontStyle(font.style.ifEmpty { null }),
265
+ ReactTypefaceUtils.parseFontWeight(font.weight.ifEmpty { null }),
266
+ font.family.ifEmpty { null },
267
+ view.context.assets
268
+ )
269
+ }
270
+ PCThemeSupport.capTextSize(view, font.maxFontSizeMultiplier)
271
+ } else if (view is ViewGroup) {
272
+ for (i in 0 until view.childCount) styleLabels(view.getChildAt(i), font)
273
+ }
274
+ }
275
+
276
+ /**
277
+ * The tab's icon, and a checked-state drawable with its selected icon when
278
+ * there is one. Drawable names and bundled assets resolve synchronously;
279
+ * other image URIs load in the background.
280
+ */
281
+ private fun loadItemIcon(
282
+ context: Context,
283
+ tab: Item,
284
+ tint: ColorStateList?,
285
+ isCurrent: () -> Boolean,
286
+ apply: (Drawable?) -> Unit
287
+ ) {
288
+ var normal: Drawable? = null
289
+ var selected: Drawable? = null
290
+ fun tinted(drawable: Drawable?, enabled: Boolean): Drawable? =
291
+ drawable?.mutate()?.apply { if (enabled) setTintList(tint) }
292
+ var pending = 1 + (if (tab.selectedIcon.isPresent) 1 else 0)
293
+ fun done() {
294
+ pending -= 1
295
+ if (pending > 0 || !isCurrent()) return
296
+ val sel = selected
297
+ apply(
298
+ if (sel == null) normal
299
+ else StateListDrawable().apply {
300
+ addState(intArrayOf(android.R.attr.state_checked), sel)
301
+ normal?.let { addState(intArrayOf(), it) }
302
+ }
303
+ )
304
+ }
305
+ if (tab.role == "search" && !tab.icon.isPresent) {
306
+ normal = tinted(ContextCompat.getDrawable(context, R.drawable.pc_ic_search), true)
307
+ done()
308
+ } else {
309
+ loadIcon(context, tab.icon) { normal = tinted(it, tab.icon.tinted); done() }
310
+ }
311
+ if (tab.selectedIcon.isPresent) {
312
+ loadIcon(context, tab.selectedIcon) { selected = tinted(it, tab.selectedIcon.tinted); done() }
313
+ }
314
+ }
315
+
316
+ private fun loadIcon(context: Context, icon: PCButtonSupport.Icon, onLoaded: (Drawable?) -> Unit) {
317
+ when (icon.type) {
318
+ "drawable" -> onLoaded(ResourceDrawableIdHelper.instance.getResourceDrawable(context, icon.name))
319
+ "image" -> {
320
+ val uri = icon.uri
321
+ if (!uri.contains(':')) {
322
+ onLoaded(ResourceDrawableIdHelper.instance.getResourceDrawable(context, uri))
323
+ } else {
324
+ PCImageLoader.load(context, uri, icon.scale, icon.request) { bitmap ->
325
+ onLoaded(bitmap?.let { BitmapDrawable(context.resources, it) })
326
+ }
327
+ }
328
+ }
329
+ else -> onLoaded(null)
330
+ }
331
+ }
332
+ }