react-native-platform-components 1.3.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 (636) hide show
  1. package/PlatformComponents.podspec +1 -1
  2. package/README.md +47 -51
  3. package/android/src/main/java/com/platformcomponents/PCButtonGroupView.kt +664 -0
  4. package/android/src/main/java/com/platformcomponents/PCButtonGroupViewManager.kt +241 -0
  5. package/android/src/main/java/com/platformcomponents/PCButtonSupport.kt +159 -0
  6. package/android/src/main/java/com/platformcomponents/PCButtonView.kt +527 -0
  7. package/android/src/main/java/com/platformcomponents/PCButtonViewManager.kt +204 -0
  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 +112 -0
  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 +247 -0
  16. package/android/src/main/java/com/platformcomponents/PCFloatingToolbarViewManager.kt +73 -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 +35 -17
  28. package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +20 -3
  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 +1393 -0
  34. package/android/src/main/java/com/platformcomponents/PCTextFieldViewManager.kt +354 -0
  35. package/android/src/main/java/com/platformcomponents/PCThemeSupport.kt +37 -0
  36. package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +8 -0
  37. package/android/src/main/res/drawable/pc_ic_search.xml +12 -0
  38. package/android/src/main/res/values/attrs.xml +13 -0
  39. package/android/src/main/res/values/ids.xml +5 -0
  40. package/android/src/main/res/values/styles.xml +207 -0
  41. package/ios/PCButton.h +10 -0
  42. package/ios/PCButton.mm +311 -0
  43. package/ios/PCButtonGroup.h +10 -0
  44. package/ios/PCButtonGroup.mm +323 -0
  45. package/ios/PCButtonGroupView.swift +473 -0
  46. package/ios/PCButtonSupport.swift +312 -0
  47. package/ios/PCButtonView.swift +438 -0
  48. package/ios/PCConstants.swift +23 -2
  49. package/ios/PCContextMenu.mm +28 -110
  50. package/ios/PCContextMenu.swift +106 -167
  51. package/ios/PCDatePicker.mm +21 -9
  52. package/ios/PCDatePickerView.swift +94 -20
  53. package/ios/PCFloatingActionButton.h +10 -0
  54. package/ios/PCFloatingActionButton.mm +177 -0
  55. package/ios/PCFloatingActionButtonView.swift +426 -0
  56. package/ios/PCFloatingToolbar.h +10 -0
  57. package/ios/PCFloatingToolbar.mm +103 -0
  58. package/ios/PCFloatingToolbarView.swift +336 -0
  59. package/ios/PCHaptics.swift +91 -0
  60. package/ios/PCImageLoader.swift +76 -12
  61. package/ios/PCLiquidGlass.mm +36 -0
  62. package/ios/PCLiquidGlass.swift +221 -114
  63. package/ios/PCLiquidGlassContainer.h +10 -0
  64. package/ios/PCLiquidGlassContainer.mm +84 -0
  65. package/ios/PCLiquidGlassContainer.swift +69 -0
  66. package/ios/PCMenuItems.h +76 -0
  67. package/ios/PCMenuSupport.swift +350 -0
  68. package/ios/PCNavigationRail.h +10 -0
  69. package/ios/PCNavigationRail.mm +270 -0
  70. package/ios/PCNavigationRailView.swift +415 -0
  71. package/ios/PCSegmentedControl.mm +17 -2
  72. package/ios/PCSegmentedControl.swift +57 -7
  73. package/ios/PCSelectionMenu.mm +36 -8
  74. package/ios/PCSelectionMenu.swift +224 -48
  75. package/ios/PCTabBar.h +10 -0
  76. package/ios/PCTabBar.mm +285 -0
  77. package/ios/PCTabBarAccessory.h +10 -0
  78. package/ios/PCTabBarAccessory.mm +93 -0
  79. package/ios/PCTabBarAccessoryView.swift +96 -0
  80. package/ios/PCTabBarView.swift +671 -0
  81. package/ios/PCTextField.h +10 -0
  82. package/ios/PCTextField.mm +546 -0
  83. package/ios/PCTextFieldView.swift +1558 -0
  84. package/lib/commonjs/Button.js +149 -0
  85. package/lib/commonjs/Button.js.map +1 -0
  86. package/lib/commonjs/ButtonGroup.js +109 -0
  87. package/lib/commonjs/ButtonGroup.js.map +1 -0
  88. package/lib/commonjs/ButtonGroupNativeComponent.ts +191 -0
  89. package/lib/commonjs/ButtonNativeComponent.ts +192 -0
  90. package/lib/commonjs/ContextMenu.js +9 -48
  91. package/lib/commonjs/ContextMenu.js.map +1 -1
  92. package/lib/commonjs/ContextMenuNativeComponent.ts +47 -49
  93. package/lib/commonjs/DatePicker.js +98 -2
  94. package/lib/commonjs/DatePicker.js.map +1 -1
  95. package/lib/commonjs/DatePickerNativeComponent.ts +19 -2
  96. package/lib/commonjs/FloatingActionButton.js +60 -0
  97. package/lib/commonjs/FloatingActionButton.js.map +1 -0
  98. package/lib/commonjs/FloatingActionButtonNativeComponent.ts +58 -0
  99. package/lib/commonjs/FloatingToolbar.js +77 -0
  100. package/lib/commonjs/FloatingToolbar.js.map +1 -0
  101. package/lib/commonjs/FloatingToolbarNativeComponent.ts +47 -0
  102. package/lib/commonjs/LiquidGlass.js +7 -1
  103. package/lib/commonjs/LiquidGlass.js.map +1 -1
  104. package/lib/commonjs/LiquidGlassContainer.js +32 -0
  105. package/lib/commonjs/LiquidGlassContainer.js.map +1 -0
  106. package/lib/commonjs/LiquidGlassContainerNativeComponent.ts +17 -0
  107. package/lib/commonjs/LiquidGlassNativeComponent.ts +8 -0
  108. package/lib/commonjs/NavigationRail.js +104 -0
  109. package/lib/commonjs/NavigationRail.js.map +1 -0
  110. package/lib/commonjs/NavigationRailNativeComponent.ts +107 -0
  111. package/lib/commonjs/PlatformComponentsProvider.js +18 -0
  112. package/lib/commonjs/PlatformComponentsProvider.js.map +1 -0
  113. package/lib/commonjs/SegmentedControl.js +18 -85
  114. package/lib/commonjs/SegmentedControl.js.map +1 -1
  115. package/lib/commonjs/SegmentedControlNativeComponent.ts +14 -0
  116. package/lib/commonjs/SelectionMenu.js +27 -3
  117. package/lib/commonjs/SelectionMenu.js.map +1 -1
  118. package/lib/commonjs/SelectionMenuNativeComponent.ts +26 -4
  119. package/lib/commonjs/SplitButton.js +98 -0
  120. package/lib/commonjs/SplitButton.js.map +1 -0
  121. package/lib/commonjs/TabBar.js +203 -0
  122. package/lib/commonjs/TabBar.js.map +1 -0
  123. package/lib/commonjs/TabBarAccessoryNativeComponent.ts +19 -0
  124. package/lib/commonjs/TabBarNativeComponent.ts +145 -0
  125. package/lib/commonjs/TextField.js +358 -0
  126. package/lib/commonjs/TextField.js.map +1 -0
  127. package/lib/commonjs/TextFieldNativeComponent.ts +324 -0
  128. package/lib/commonjs/focusRegistry.js +79 -0
  129. package/lib/commonjs/focusRegistry.js.map +1 -0
  130. package/lib/commonjs/haptics.js +2 -0
  131. package/lib/commonjs/haptics.js.map +1 -0
  132. package/lib/commonjs/icons.js +106 -0
  133. package/lib/commonjs/icons.js.map +1 -0
  134. package/lib/commonjs/index.js +143 -0
  135. package/lib/commonjs/index.js.map +1 -1
  136. package/lib/commonjs/index.web.js +157 -63
  137. package/lib/commonjs/index.web.js.map +1 -1
  138. package/lib/commonjs/jest.js +910 -0
  139. package/lib/commonjs/jest.js.map +1 -0
  140. package/lib/commonjs/labelStyle.js +27 -0
  141. package/lib/commonjs/labelStyle.js.map +1 -0
  142. package/lib/commonjs/menuItems.js +68 -0
  143. package/lib/commonjs/menuItems.js.map +1 -0
  144. package/lib/commonjs/reactNativeInternals.d.js +2 -0
  145. package/lib/commonjs/reactNativeInternals.d.js.map +1 -0
  146. package/lib/commonjs/selectionIdentifiers.js +18 -0
  147. package/lib/commonjs/selectionIdentifiers.js.map +1 -0
  148. package/lib/commonjs/submitBehavior.js +19 -0
  149. package/lib/commonjs/submitBehavior.js.map +1 -0
  150. package/lib/commonjs/tabItems.js +49 -0
  151. package/lib/commonjs/tabItems.js.map +1 -0
  152. package/lib/commonjs/web/Button.js +170 -0
  153. package/lib/commonjs/web/Button.js.map +1 -0
  154. package/lib/commonjs/web/ButtonGroup.js +119 -0
  155. package/lib/commonjs/web/ButtonGroup.js.map +1 -0
  156. package/lib/commonjs/web/DatePicker.js +168 -0
  157. package/lib/commonjs/web/DatePicker.js.map +1 -0
  158. package/lib/commonjs/web/DateRangePicker.js +137 -0
  159. package/lib/commonjs/web/DateRangePicker.js.map +1 -0
  160. package/lib/commonjs/web/Dialog.js +54 -0
  161. package/lib/commonjs/web/Dialog.js.map +1 -0
  162. package/lib/commonjs/web/FloatingActionButton.js +98 -0
  163. package/lib/commonjs/web/FloatingActionButton.js.map +1 -0
  164. package/lib/commonjs/web/Icon.js +34 -0
  165. package/lib/commonjs/web/Icon.js.map +1 -0
  166. package/lib/commonjs/web/NativeTheme.js +28 -0
  167. package/lib/commonjs/web/NativeTheme.js.map +1 -0
  168. package/lib/commonjs/web/NavigationRail.js +139 -0
  169. package/lib/commonjs/web/NavigationRail.js.map +1 -0
  170. package/lib/commonjs/web/PlatformComponentsProvider.js +51 -0
  171. package/lib/commonjs/web/PlatformComponentsProvider.js.map +1 -0
  172. package/lib/commonjs/web/SegmentedControl.js +117 -0
  173. package/lib/commonjs/web/SegmentedControl.js.map +1 -0
  174. package/lib/commonjs/web/SelectionMenu.js +142 -0
  175. package/lib/commonjs/web/SelectionMenu.js.map +1 -0
  176. package/lib/commonjs/web/SplitButton.js +35 -0
  177. package/lib/commonjs/web/SplitButton.js.map +1 -0
  178. package/lib/commonjs/web/TabBar.js +131 -0
  179. package/lib/commonjs/web/TabBar.js.map +1 -0
  180. package/lib/commonjs/web/TextField.js +322 -0
  181. package/lib/commonjs/web/TextField.js.map +1 -0
  182. package/lib/commonjs/web/components.js +36 -0
  183. package/lib/commonjs/web/components.js.map +1 -0
  184. package/lib/commonjs/web/containers.js +121 -0
  185. package/lib/commonjs/web/containers.js.map +1 -0
  186. package/lib/commonjs/web/dateInput.js +116 -0
  187. package/lib/commonjs/web/dateInput.js.map +1 -0
  188. package/lib/commonjs/web/shared.js +192 -0
  189. package/lib/commonjs/web/shared.js.map +1 -0
  190. package/lib/commonjs/webComponents.js +6 -0
  191. package/lib/commonjs/webComponents.js.map +1 -0
  192. package/lib/module/Button.js +142 -0
  193. package/lib/module/Button.js.map +1 -0
  194. package/lib/module/ButtonGroup.js +102 -0
  195. package/lib/module/ButtonGroup.js.map +1 -0
  196. package/lib/module/ButtonGroupNativeComponent.ts +191 -0
  197. package/lib/module/ButtonNativeComponent.ts +192 -0
  198. package/lib/module/ContextMenu.js +9 -48
  199. package/lib/module/ContextMenu.js.map +1 -1
  200. package/lib/module/ContextMenuNativeComponent.ts +47 -49
  201. package/lib/module/DatePicker.js +98 -4
  202. package/lib/module/DatePicker.js.map +1 -1
  203. package/lib/module/DatePickerNativeComponent.ts +19 -2
  204. package/lib/module/FloatingActionButton.js +53 -0
  205. package/lib/module/FloatingActionButton.js.map +1 -0
  206. package/lib/module/FloatingActionButtonNativeComponent.ts +58 -0
  207. package/lib/module/FloatingToolbar.js +70 -0
  208. package/lib/module/FloatingToolbar.js.map +1 -0
  209. package/lib/module/FloatingToolbarNativeComponent.ts +47 -0
  210. package/lib/module/LiquidGlass.js +7 -1
  211. package/lib/module/LiquidGlass.js.map +1 -1
  212. package/lib/module/LiquidGlassContainer.js +26 -0
  213. package/lib/module/LiquidGlassContainer.js.map +1 -0
  214. package/lib/module/LiquidGlassContainerNativeComponent.ts +17 -0
  215. package/lib/module/LiquidGlassNativeComponent.ts +8 -0
  216. package/lib/module/NavigationRail.js +99 -0
  217. package/lib/module/NavigationRail.js.map +1 -0
  218. package/lib/module/NavigationRailNativeComponent.ts +107 -0
  219. package/lib/module/PlatformComponentsProvider.js +13 -0
  220. package/lib/module/PlatformComponentsProvider.js.map +1 -0
  221. package/lib/module/SegmentedControl.js +18 -85
  222. package/lib/module/SegmentedControl.js.map +1 -1
  223. package/lib/module/SegmentedControlNativeComponent.ts +14 -0
  224. package/lib/module/SelectionMenu.js +27 -3
  225. package/lib/module/SelectionMenu.js.map +1 -1
  226. package/lib/module/SelectionMenuNativeComponent.ts +26 -4
  227. package/lib/module/SplitButton.js +91 -0
  228. package/lib/module/SplitButton.js.map +1 -0
  229. package/lib/module/TabBar.js +196 -0
  230. package/lib/module/TabBar.js.map +1 -0
  231. package/lib/module/TabBarAccessoryNativeComponent.ts +19 -0
  232. package/lib/module/TabBarNativeComponent.ts +145 -0
  233. package/lib/module/TextField.js +352 -0
  234. package/lib/module/TextField.js.map +1 -0
  235. package/lib/module/TextFieldNativeComponent.ts +324 -0
  236. package/lib/module/focusRegistry.js +75 -0
  237. package/lib/module/focusRegistry.js.map +1 -0
  238. package/lib/module/haptics.js +2 -0
  239. package/lib/module/haptics.js.map +1 -0
  240. package/lib/module/icons.js +101 -0
  241. package/lib/module/icons.js.map +1 -0
  242. package/lib/module/index.js +13 -0
  243. package/lib/module/index.js.map +1 -1
  244. package/lib/module/index.web.js +12 -59
  245. package/lib/module/index.web.js.map +1 -1
  246. package/lib/module/jest.js +840 -0
  247. package/lib/module/jest.js.map +1 -0
  248. package/lib/module/labelStyle.js +23 -0
  249. package/lib/module/labelStyle.js.map +1 -0
  250. package/lib/module/menuItems.js +65 -0
  251. package/lib/module/menuItems.js.map +1 -0
  252. package/lib/module/reactNativeInternals.d.js +2 -0
  253. package/lib/module/reactNativeInternals.d.js.map +1 -0
  254. package/lib/module/selectionIdentifiers.js +14 -0
  255. package/lib/module/selectionIdentifiers.js.map +1 -0
  256. package/lib/module/submitBehavior.js +15 -0
  257. package/lib/module/submitBehavior.js.map +1 -0
  258. package/lib/module/tabItems.js +45 -0
  259. package/lib/module/tabItems.js.map +1 -0
  260. package/lib/module/web/Button.js +164 -0
  261. package/lib/module/web/Button.js.map +1 -0
  262. package/lib/module/web/ButtonGroup.js +113 -0
  263. package/lib/module/web/ButtonGroup.js.map +1 -0
  264. package/lib/module/web/DatePicker.js +162 -0
  265. package/lib/module/web/DatePicker.js.map +1 -0
  266. package/lib/module/web/DateRangePicker.js +131 -0
  267. package/lib/module/web/DateRangePicker.js.map +1 -0
  268. package/lib/module/web/Dialog.js +48 -0
  269. package/lib/module/web/Dialog.js.map +1 -0
  270. package/lib/module/web/FloatingActionButton.js +94 -0
  271. package/lib/module/web/FloatingActionButton.js.map +1 -0
  272. package/lib/module/web/Icon.js +29 -0
  273. package/lib/module/web/Icon.js.map +1 -0
  274. package/lib/module/web/NativeTheme.js +23 -0
  275. package/lib/module/web/NativeTheme.js.map +1 -0
  276. package/lib/module/web/NavigationRail.js +133 -0
  277. package/lib/module/web/NavigationRail.js.map +1 -0
  278. package/lib/module/web/PlatformComponentsProvider.js +44 -0
  279. package/lib/module/web/PlatformComponentsProvider.js.map +1 -0
  280. package/lib/module/web/SegmentedControl.js +112 -0
  281. package/lib/module/web/SegmentedControl.js.map +1 -0
  282. package/lib/module/web/SelectionMenu.js +137 -0
  283. package/lib/module/web/SelectionMenu.js.map +1 -0
  284. package/lib/module/web/SplitButton.js +30 -0
  285. package/lib/module/web/SplitButton.js.map +1 -0
  286. package/lib/module/web/TabBar.js +126 -0
  287. package/lib/module/web/TabBar.js.map +1 -0
  288. package/lib/module/web/TextField.js +316 -0
  289. package/lib/module/web/TextField.js.map +1 -0
  290. package/lib/module/web/components.js +33 -0
  291. package/lib/module/web/components.js.map +1 -0
  292. package/lib/module/web/containers.js +112 -0
  293. package/lib/module/web/containers.js.map +1 -0
  294. package/lib/module/web/dateInput.js +109 -0
  295. package/lib/module/web/dateInput.js.map +1 -0
  296. package/lib/module/web/shared.js +179 -0
  297. package/lib/module/web/shared.js.map +1 -0
  298. package/lib/module/webComponents.js +4 -0
  299. package/lib/module/webComponents.js.map +1 -0
  300. package/lib/typescript/commonjs/docs/sidebars.d.ts.map +1 -1
  301. package/lib/typescript/commonjs/src/Button.d.ts +184 -0
  302. package/lib/typescript/commonjs/src/Button.d.ts.map +1 -0
  303. package/lib/typescript/commonjs/src/ButtonGroup.d.ts +117 -0
  304. package/lib/typescript/commonjs/src/ButtonGroup.d.ts.map +1 -0
  305. package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts +154 -0
  306. package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts.map +1 -0
  307. package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts +148 -0
  308. package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts.map +1 -0
  309. package/lib/typescript/commonjs/src/ContextMenu.d.ts +20 -33
  310. package/lib/typescript/commonjs/src/ContextMenu.d.ts.map +1 -1
  311. package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts +45 -47
  312. package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts.map +1 -1
  313. package/lib/typescript/commonjs/src/DatePicker.d.ts +74 -1
  314. package/lib/typescript/commonjs/src/DatePicker.d.ts.map +1 -1
  315. package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts +16 -1
  316. package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts.map +1 -1
  317. package/lib/typescript/commonjs/src/FloatingActionButton.d.ts +67 -0
  318. package/lib/typescript/commonjs/src/FloatingActionButton.d.ts.map +1 -0
  319. package/lib/typescript/commonjs/src/FloatingActionButtonNativeComponent.d.ts +43 -0
  320. package/lib/typescript/commonjs/src/FloatingActionButtonNativeComponent.d.ts.map +1 -0
  321. package/lib/typescript/commonjs/src/FloatingToolbar.d.ts +75 -0
  322. package/lib/typescript/commonjs/src/FloatingToolbar.d.ts.map +1 -0
  323. package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts +36 -0
  324. package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
  325. package/lib/typescript/commonjs/src/LiquidGlass.d.ts +17 -0
  326. package/lib/typescript/commonjs/src/LiquidGlass.d.ts.map +1 -1
  327. package/lib/typescript/commonjs/src/LiquidGlassContainer.d.ts +27 -0
  328. package/lib/typescript/commonjs/src/LiquidGlassContainer.d.ts.map +1 -0
  329. package/lib/typescript/commonjs/src/LiquidGlassContainerNativeComponent.d.ts +13 -0
  330. package/lib/typescript/commonjs/src/LiquidGlassContainerNativeComponent.d.ts.map +1 -0
  331. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts +7 -0
  332. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts.map +1 -1
  333. package/lib/typescript/commonjs/src/NavigationRail.d.ts +86 -0
  334. package/lib/typescript/commonjs/src/NavigationRail.d.ts.map +1 -0
  335. package/lib/typescript/commonjs/src/NavigationRailNativeComponent.d.ts +81 -0
  336. package/lib/typescript/commonjs/src/NavigationRailNativeComponent.d.ts.map +1 -0
  337. package/lib/typescript/commonjs/src/PlatformComponentsProvider.d.ts +6 -0
  338. package/lib/typescript/commonjs/src/PlatformComponentsProvider.d.ts.map +1 -0
  339. package/lib/typescript/commonjs/src/SegmentedControl.d.ts +35 -47
  340. package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -1
  341. package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +11 -0
  342. package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -1
  343. package/lib/typescript/commonjs/src/SelectionMenu.d.ts +44 -2
  344. package/lib/typescript/commonjs/src/SelectionMenu.d.ts.map +1 -1
  345. package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts +20 -4
  346. package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts.map +1 -1
  347. package/lib/typescript/commonjs/src/SplitButton.d.ts +83 -0
  348. package/lib/typescript/commonjs/src/SplitButton.d.ts.map +1 -0
  349. package/lib/typescript/commonjs/src/TabBar.d.ts +144 -0
  350. package/lib/typescript/commonjs/src/TabBar.d.ts.map +1 -0
  351. package/lib/typescript/commonjs/src/TabBarAccessoryNativeComponent.d.ts +13 -0
  352. package/lib/typescript/commonjs/src/TabBarAccessoryNativeComponent.d.ts.map +1 -0
  353. package/lib/typescript/commonjs/src/TabBarNativeComponent.d.ts +110 -0
  354. package/lib/typescript/commonjs/src/TabBarNativeComponent.d.ts.map +1 -0
  355. package/lib/typescript/commonjs/src/TextField.d.ts +332 -0
  356. package/lib/typescript/commonjs/src/TextField.d.ts.map +1 -0
  357. package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts +240 -0
  358. package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts.map +1 -0
  359. package/lib/typescript/commonjs/src/focusRegistry.d.ts +13 -0
  360. package/lib/typescript/commonjs/src/focusRegistry.d.ts.map +1 -0
  361. package/lib/typescript/commonjs/src/haptics.d.ts +20 -0
  362. package/lib/typescript/commonjs/src/haptics.d.ts.map +1 -0
  363. package/lib/typescript/commonjs/src/icons.d.ts +58 -0
  364. package/lib/typescript/commonjs/src/icons.d.ts.map +1 -0
  365. package/lib/typescript/commonjs/src/index.d.ts +13 -0
  366. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  367. package/lib/typescript/commonjs/src/index.web.d.ts +25 -133
  368. package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
  369. package/lib/typescript/commonjs/src/jest.d.ts +139 -0
  370. package/lib/typescript/commonjs/src/jest.d.ts.map +1 -0
  371. package/lib/typescript/commonjs/src/labelStyle.d.ts +20 -0
  372. package/lib/typescript/commonjs/src/labelStyle.d.ts.map +1 -0
  373. package/lib/typescript/commonjs/src/menuItems.d.ts +100 -0
  374. package/lib/typescript/commonjs/src/menuItems.d.ts.map +1 -0
  375. package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts +3 -0
  376. package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts.map +1 -0
  377. package/lib/typescript/commonjs/src/sharedTypes.d.ts +6 -1
  378. package/lib/typescript/commonjs/src/sharedTypes.d.ts.map +1 -1
  379. package/lib/typescript/commonjs/src/submitBehavior.d.ts +9 -0
  380. package/lib/typescript/commonjs/src/submitBehavior.d.ts.map +1 -0
  381. package/lib/typescript/commonjs/src/tabItems.d.ts +55 -0
  382. package/lib/typescript/commonjs/src/tabItems.d.ts.map +1 -0
  383. package/lib/typescript/commonjs/src/web/Button.d.ts +9 -0
  384. package/lib/typescript/commonjs/src/web/Button.d.ts.map +1 -0
  385. package/lib/typescript/commonjs/src/web/ButtonGroup.d.ts +11 -0
  386. package/lib/typescript/commonjs/src/web/ButtonGroup.d.ts.map +1 -0
  387. package/lib/typescript/commonjs/src/web/DatePicker.d.ts +14 -0
  388. package/lib/typescript/commonjs/src/web/DatePicker.d.ts.map +1 -0
  389. package/lib/typescript/commonjs/src/web/DateRangePicker.d.ts +11 -0
  390. package/lib/typescript/commonjs/src/web/DateRangePicker.d.ts.map +1 -0
  391. package/lib/typescript/commonjs/src/web/Dialog.d.ts +12 -0
  392. package/lib/typescript/commonjs/src/web/Dialog.d.ts.map +1 -0
  393. package/lib/typescript/commonjs/src/web/FloatingActionButton.d.ts +8 -0
  394. package/lib/typescript/commonjs/src/web/FloatingActionButton.d.ts.map +1 -0
  395. package/lib/typescript/commonjs/src/web/Icon.d.ts +12 -0
  396. package/lib/typescript/commonjs/src/web/Icon.d.ts.map +1 -0
  397. package/lib/typescript/commonjs/src/web/NativeTheme.d.ts +10 -0
  398. package/lib/typescript/commonjs/src/web/NativeTheme.d.ts.map +1 -0
  399. package/lib/typescript/commonjs/src/web/NavigationRail.d.ts +8 -0
  400. package/lib/typescript/commonjs/src/web/NavigationRail.d.ts.map +1 -0
  401. package/lib/typescript/commonjs/src/web/PlatformComponentsProvider.d.ts +10 -0
  402. package/lib/typescript/commonjs/src/web/PlatformComponentsProvider.d.ts.map +1 -0
  403. package/lib/typescript/commonjs/src/web/SegmentedControl.d.ts +8 -0
  404. package/lib/typescript/commonjs/src/web/SegmentedControl.d.ts.map +1 -0
  405. package/lib/typescript/commonjs/src/web/SelectionMenu.d.ts +10 -0
  406. package/lib/typescript/commonjs/src/web/SelectionMenu.d.ts.map +1 -0
  407. package/lib/typescript/commonjs/src/web/SplitButton.d.ts +9 -0
  408. package/lib/typescript/commonjs/src/web/SplitButton.d.ts.map +1 -0
  409. package/lib/typescript/commonjs/src/web/TabBar.d.ts +9 -0
  410. package/lib/typescript/commonjs/src/web/TabBar.d.ts.map +1 -0
  411. package/lib/typescript/commonjs/src/web/TextField.d.ts +9 -0
  412. package/lib/typescript/commonjs/src/web/TextField.d.ts.map +1 -0
  413. package/lib/typescript/commonjs/src/web/components.d.ts +17 -0
  414. package/lib/typescript/commonjs/src/web/components.d.ts.map +1 -0
  415. package/lib/typescript/commonjs/src/web/containers.d.ts +24 -0
  416. package/lib/typescript/commonjs/src/web/containers.d.ts.map +1 -0
  417. package/lib/typescript/commonjs/src/web/dateInput.d.ts +20 -0
  418. package/lib/typescript/commonjs/src/web/dateInput.d.ts.map +1 -0
  419. package/lib/typescript/commonjs/src/web/shared.d.ts +43 -0
  420. package/lib/typescript/commonjs/src/web/shared.d.ts.map +1 -0
  421. package/lib/typescript/commonjs/src/webComponents.d.ts +43 -0
  422. package/lib/typescript/commonjs/src/webComponents.d.ts.map +1 -0
  423. package/lib/typescript/module/docs/sidebars.d.ts.map +1 -1
  424. package/lib/typescript/module/src/Button.d.ts +184 -0
  425. package/lib/typescript/module/src/Button.d.ts.map +1 -0
  426. package/lib/typescript/module/src/ButtonGroup.d.ts +117 -0
  427. package/lib/typescript/module/src/ButtonGroup.d.ts.map +1 -0
  428. package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts +154 -0
  429. package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts.map +1 -0
  430. package/lib/typescript/module/src/ButtonNativeComponent.d.ts +148 -0
  431. package/lib/typescript/module/src/ButtonNativeComponent.d.ts.map +1 -0
  432. package/lib/typescript/module/src/ContextMenu.d.ts +20 -33
  433. package/lib/typescript/module/src/ContextMenu.d.ts.map +1 -1
  434. package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts +45 -47
  435. package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts.map +1 -1
  436. package/lib/typescript/module/src/DatePicker.d.ts +74 -1
  437. package/lib/typescript/module/src/DatePicker.d.ts.map +1 -1
  438. package/lib/typescript/module/src/DatePickerNativeComponent.d.ts +16 -1
  439. package/lib/typescript/module/src/DatePickerNativeComponent.d.ts.map +1 -1
  440. package/lib/typescript/module/src/FloatingActionButton.d.ts +67 -0
  441. package/lib/typescript/module/src/FloatingActionButton.d.ts.map +1 -0
  442. package/lib/typescript/module/src/FloatingActionButtonNativeComponent.d.ts +43 -0
  443. package/lib/typescript/module/src/FloatingActionButtonNativeComponent.d.ts.map +1 -0
  444. package/lib/typescript/module/src/FloatingToolbar.d.ts +75 -0
  445. package/lib/typescript/module/src/FloatingToolbar.d.ts.map +1 -0
  446. package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts +36 -0
  447. package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
  448. package/lib/typescript/module/src/LiquidGlass.d.ts +17 -0
  449. package/lib/typescript/module/src/LiquidGlass.d.ts.map +1 -1
  450. package/lib/typescript/module/src/LiquidGlassContainer.d.ts +27 -0
  451. package/lib/typescript/module/src/LiquidGlassContainer.d.ts.map +1 -0
  452. package/lib/typescript/module/src/LiquidGlassContainerNativeComponent.d.ts +13 -0
  453. package/lib/typescript/module/src/LiquidGlassContainerNativeComponent.d.ts.map +1 -0
  454. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts +7 -0
  455. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts.map +1 -1
  456. package/lib/typescript/module/src/NavigationRail.d.ts +86 -0
  457. package/lib/typescript/module/src/NavigationRail.d.ts.map +1 -0
  458. package/lib/typescript/module/src/NavigationRailNativeComponent.d.ts +81 -0
  459. package/lib/typescript/module/src/NavigationRailNativeComponent.d.ts.map +1 -0
  460. package/lib/typescript/module/src/PlatformComponentsProvider.d.ts +6 -0
  461. package/lib/typescript/module/src/PlatformComponentsProvider.d.ts.map +1 -0
  462. package/lib/typescript/module/src/SegmentedControl.d.ts +35 -47
  463. package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -1
  464. package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +11 -0
  465. package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -1
  466. package/lib/typescript/module/src/SelectionMenu.d.ts +44 -2
  467. package/lib/typescript/module/src/SelectionMenu.d.ts.map +1 -1
  468. package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts +20 -4
  469. package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts.map +1 -1
  470. package/lib/typescript/module/src/SplitButton.d.ts +83 -0
  471. package/lib/typescript/module/src/SplitButton.d.ts.map +1 -0
  472. package/lib/typescript/module/src/TabBar.d.ts +144 -0
  473. package/lib/typescript/module/src/TabBar.d.ts.map +1 -0
  474. package/lib/typescript/module/src/TabBarAccessoryNativeComponent.d.ts +13 -0
  475. package/lib/typescript/module/src/TabBarAccessoryNativeComponent.d.ts.map +1 -0
  476. package/lib/typescript/module/src/TabBarNativeComponent.d.ts +110 -0
  477. package/lib/typescript/module/src/TabBarNativeComponent.d.ts.map +1 -0
  478. package/lib/typescript/module/src/TextField.d.ts +332 -0
  479. package/lib/typescript/module/src/TextField.d.ts.map +1 -0
  480. package/lib/typescript/module/src/TextFieldNativeComponent.d.ts +240 -0
  481. package/lib/typescript/module/src/TextFieldNativeComponent.d.ts.map +1 -0
  482. package/lib/typescript/module/src/focusRegistry.d.ts +13 -0
  483. package/lib/typescript/module/src/focusRegistry.d.ts.map +1 -0
  484. package/lib/typescript/module/src/haptics.d.ts +20 -0
  485. package/lib/typescript/module/src/haptics.d.ts.map +1 -0
  486. package/lib/typescript/module/src/icons.d.ts +58 -0
  487. package/lib/typescript/module/src/icons.d.ts.map +1 -0
  488. package/lib/typescript/module/src/index.d.ts +13 -0
  489. package/lib/typescript/module/src/index.d.ts.map +1 -1
  490. package/lib/typescript/module/src/index.web.d.ts +25 -133
  491. package/lib/typescript/module/src/index.web.d.ts.map +1 -1
  492. package/lib/typescript/module/src/jest.d.ts +139 -0
  493. package/lib/typescript/module/src/jest.d.ts.map +1 -0
  494. package/lib/typescript/module/src/labelStyle.d.ts +20 -0
  495. package/lib/typescript/module/src/labelStyle.d.ts.map +1 -0
  496. package/lib/typescript/module/src/menuItems.d.ts +100 -0
  497. package/lib/typescript/module/src/menuItems.d.ts.map +1 -0
  498. package/lib/typescript/module/src/selectionIdentifiers.d.ts +3 -0
  499. package/lib/typescript/module/src/selectionIdentifiers.d.ts.map +1 -0
  500. package/lib/typescript/module/src/sharedTypes.d.ts +6 -1
  501. package/lib/typescript/module/src/sharedTypes.d.ts.map +1 -1
  502. package/lib/typescript/module/src/submitBehavior.d.ts +9 -0
  503. package/lib/typescript/module/src/submitBehavior.d.ts.map +1 -0
  504. package/lib/typescript/module/src/tabItems.d.ts +55 -0
  505. package/lib/typescript/module/src/tabItems.d.ts.map +1 -0
  506. package/lib/typescript/module/src/web/Button.d.ts +9 -0
  507. package/lib/typescript/module/src/web/Button.d.ts.map +1 -0
  508. package/lib/typescript/module/src/web/ButtonGroup.d.ts +11 -0
  509. package/lib/typescript/module/src/web/ButtonGroup.d.ts.map +1 -0
  510. package/lib/typescript/module/src/web/DatePicker.d.ts +14 -0
  511. package/lib/typescript/module/src/web/DatePicker.d.ts.map +1 -0
  512. package/lib/typescript/module/src/web/DateRangePicker.d.ts +11 -0
  513. package/lib/typescript/module/src/web/DateRangePicker.d.ts.map +1 -0
  514. package/lib/typescript/module/src/web/Dialog.d.ts +12 -0
  515. package/lib/typescript/module/src/web/Dialog.d.ts.map +1 -0
  516. package/lib/typescript/module/src/web/FloatingActionButton.d.ts +8 -0
  517. package/lib/typescript/module/src/web/FloatingActionButton.d.ts.map +1 -0
  518. package/lib/typescript/module/src/web/Icon.d.ts +12 -0
  519. package/lib/typescript/module/src/web/Icon.d.ts.map +1 -0
  520. package/lib/typescript/module/src/web/NativeTheme.d.ts +10 -0
  521. package/lib/typescript/module/src/web/NativeTheme.d.ts.map +1 -0
  522. package/lib/typescript/module/src/web/NavigationRail.d.ts +8 -0
  523. package/lib/typescript/module/src/web/NavigationRail.d.ts.map +1 -0
  524. package/lib/typescript/module/src/web/PlatformComponentsProvider.d.ts +10 -0
  525. package/lib/typescript/module/src/web/PlatformComponentsProvider.d.ts.map +1 -0
  526. package/lib/typescript/module/src/web/SegmentedControl.d.ts +8 -0
  527. package/lib/typescript/module/src/web/SegmentedControl.d.ts.map +1 -0
  528. package/lib/typescript/module/src/web/SelectionMenu.d.ts +10 -0
  529. package/lib/typescript/module/src/web/SelectionMenu.d.ts.map +1 -0
  530. package/lib/typescript/module/src/web/SplitButton.d.ts +9 -0
  531. package/lib/typescript/module/src/web/SplitButton.d.ts.map +1 -0
  532. package/lib/typescript/module/src/web/TabBar.d.ts +9 -0
  533. package/lib/typescript/module/src/web/TabBar.d.ts.map +1 -0
  534. package/lib/typescript/module/src/web/TextField.d.ts +9 -0
  535. package/lib/typescript/module/src/web/TextField.d.ts.map +1 -0
  536. package/lib/typescript/module/src/web/components.d.ts +17 -0
  537. package/lib/typescript/module/src/web/components.d.ts.map +1 -0
  538. package/lib/typescript/module/src/web/containers.d.ts +24 -0
  539. package/lib/typescript/module/src/web/containers.d.ts.map +1 -0
  540. package/lib/typescript/module/src/web/dateInput.d.ts +20 -0
  541. package/lib/typescript/module/src/web/dateInput.d.ts.map +1 -0
  542. package/lib/typescript/module/src/web/shared.d.ts +43 -0
  543. package/lib/typescript/module/src/web/shared.d.ts.map +1 -0
  544. package/lib/typescript/module/src/webComponents.d.ts +43 -0
  545. package/lib/typescript/module/src/webComponents.d.ts.map +1 -0
  546. package/package.json +55 -4
  547. package/plugin/build/index.d.ts +3 -2
  548. package/plugin/build/index.d.ts.map +1 -1
  549. package/react-native.config.js +6 -0
  550. package/shared/PCButtonComponentDescriptors-custom.h +22 -0
  551. package/shared/PCButtonGroupComponentDescriptors-custom.h +22 -0
  552. package/shared/PCButtonGroupShadowNode-custom.cpp +48 -0
  553. package/shared/PCButtonGroupShadowNode-custom.h +55 -0
  554. package/shared/PCButtonGroupState-custom.h +61 -0
  555. package/shared/PCButtonShadowNode-custom.cpp +48 -0
  556. package/shared/PCButtonShadowNode-custom.h +55 -0
  557. package/shared/PCButtonState-custom.h +61 -0
  558. package/shared/PCFloatingActionButtonComponentDescriptors-custom.h +22 -0
  559. package/shared/PCFloatingActionButtonShadowNode-custom.cpp +48 -0
  560. package/shared/PCFloatingActionButtonShadowNode-custom.h +54 -0
  561. package/shared/PCFloatingActionButtonState-custom.h +61 -0
  562. package/shared/PCNavigationRailComponentDescriptors-custom.h +47 -0
  563. package/shared/PCNavigationRailShadowNode-custom.h +42 -0
  564. package/shared/PCNavigationRailState-custom.h +62 -0
  565. package/shared/PCTabBarComponentDescriptors-custom.h +22 -0
  566. package/shared/PCTabBarShadowNode-custom.cpp +54 -0
  567. package/shared/PCTabBarShadowNode-custom.h +54 -0
  568. package/shared/PCTabBarState-custom.h +62 -0
  569. package/shared/PCTextFieldComponentDescriptors-custom.h +22 -0
  570. package/shared/PCTextFieldShadowNode-custom.cpp +47 -0
  571. package/shared/PCTextFieldShadowNode-custom.h +55 -0
  572. package/shared/PCTextFieldState-custom.h +61 -0
  573. package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +6 -0
  574. package/src/Button.tsx +359 -0
  575. package/src/ButtonGroup.tsx +251 -0
  576. package/src/ButtonGroupNativeComponent.ts +191 -0
  577. package/src/ButtonNativeComponent.ts +192 -0
  578. package/src/ContextMenu.tsx +34 -81
  579. package/src/ContextMenuNativeComponent.ts +47 -49
  580. package/src/DatePicker.tsx +182 -4
  581. package/src/DatePickerNativeComponent.ts +19 -2
  582. package/src/FloatingActionButton.tsx +121 -0
  583. package/src/FloatingActionButtonNativeComponent.ts +58 -0
  584. package/src/FloatingToolbar.tsx +164 -0
  585. package/src/FloatingToolbarNativeComponent.ts +47 -0
  586. package/src/LiquidGlass.tsx +24 -1
  587. package/src/LiquidGlassContainer.tsx +42 -0
  588. package/src/LiquidGlassContainerNativeComponent.ts +17 -0
  589. package/src/LiquidGlassNativeComponent.ts +8 -0
  590. package/src/NavigationRail.tsx +203 -0
  591. package/src/NavigationRailNativeComponent.ts +107 -0
  592. package/src/PlatformComponentsProvider.tsx +15 -0
  593. package/src/SegmentedControl.tsx +57 -119
  594. package/src/SegmentedControlNativeComponent.ts +14 -0
  595. package/src/SelectionMenu.tsx +81 -6
  596. package/src/SelectionMenuNativeComponent.ts +26 -4
  597. package/src/SplitButton.tsx +198 -0
  598. package/src/TabBar.tsx +373 -0
  599. package/src/TabBarAccessoryNativeComponent.ts +19 -0
  600. package/src/TabBarNativeComponent.ts +145 -0
  601. package/src/TextField.tsx +908 -0
  602. package/src/TextFieldNativeComponent.ts +324 -0
  603. package/src/focusRegistry.ts +90 -0
  604. package/src/haptics.ts +31 -0
  605. package/src/icons.ts +143 -0
  606. package/src/index.tsx +13 -0
  607. package/src/index.web.tsx +53 -199
  608. package/src/jest.tsx +958 -0
  609. package/src/labelStyle.ts +36 -0
  610. package/src/menuItems.ts +152 -0
  611. package/src/reactNativeInternals.d.ts +22 -0
  612. package/src/selectionIdentifiers.ts +17 -0
  613. package/src/sharedTypes.ts +7 -1
  614. package/src/submitBehavior.ts +16 -0
  615. package/src/tabItems.ts +113 -0
  616. package/src/web/Button.tsx +201 -0
  617. package/src/web/ButtonGroup.tsx +154 -0
  618. package/src/web/DatePicker.tsx +204 -0
  619. package/src/web/DateRangePicker.tsx +135 -0
  620. package/src/web/Dialog.tsx +54 -0
  621. package/src/web/FloatingActionButton.tsx +76 -0
  622. package/src/web/Icon.tsx +33 -0
  623. package/src/web/NativeTheme.ts +23 -0
  624. package/src/web/NavigationRail.tsx +148 -0
  625. package/src/web/PlatformComponentsProvider.tsx +48 -0
  626. package/src/web/SegmentedControl.tsx +127 -0
  627. package/src/web/SelectionMenu.tsx +149 -0
  628. package/src/web/SplitButton.tsx +32 -0
  629. package/src/web/TabBar.tsx +150 -0
  630. package/src/web/TextField.tsx +361 -0
  631. package/src/web/components.tsx +71 -0
  632. package/src/web/containers.tsx +130 -0
  633. package/src/web/dateInput.ts +137 -0
  634. package/src/web/shared.ts +176 -0
  635. package/src/webComponents.ts +45 -0
  636. package/android/src/main/java/com/platformcomponents/DateConstraints.kt +0 -83
@@ -0,0 +1,664 @@
1
+ package com.platformcomponents
2
+
3
+ import android.content.Context
4
+ import android.content.res.ColorStateList
5
+ import android.text.TextUtils
6
+ import android.view.ContextThemeWrapper
7
+ import android.view.Gravity
8
+ import android.view.View
9
+ import android.view.ViewGroup.MarginLayoutParams
10
+ import android.widget.FrameLayout
11
+ import androidx.appcompat.widget.PopupMenu
12
+ import androidx.core.content.ContextCompat
13
+ import com.facebook.react.bridge.WritableNativeMap
14
+ import com.facebook.react.uimanager.PixelUtil
15
+ import com.facebook.react.uimanager.ReactCompoundViewGroup
16
+ import com.facebook.react.uimanager.StateWrapper
17
+ import com.facebook.react.views.scroll.ReactScrollViewHelper
18
+ import com.google.android.material.R as MaterialR
19
+ import com.google.android.material.button.MaterialButton
20
+ import com.google.android.material.button.MaterialButtonGroup
21
+ import com.google.android.material.button.MaterialButtonToggleGroup
22
+ import com.google.android.material.button.MaterialSplitButton
23
+
24
+ /**
25
+ * A Material 3 Expressive button group: MaterialButtonGroup for plain actions,
26
+ * MaterialButtonToggleGroup for single / multiple selection, and
27
+ * MaterialSplitButton in split mode (SplitButton). Rebuilt whenever a prop the
28
+ * widgets read at construction changes.
29
+ */
30
+ class PCButtonGroupView(context: Context) :
31
+ FrameLayout(context),
32
+ ReactScrollViewHelper.HasStateWrapper,
33
+ ReactCompoundViewGroup {
34
+
35
+ data class Item(
36
+ val label: String,
37
+ val value: String,
38
+ val disabled: Boolean,
39
+ val icon: PCButtonSupport.Icon,
40
+ val accessibilityLabel: String
41
+ ) {
42
+ /** What TalkBack announces for the button. */
43
+ val spokenLabel: String get() = accessibilityLabel.ifEmpty { label }
44
+ }
45
+
46
+ companion object {
47
+ private const val TAG = "PCButtonGroup"
48
+
49
+ /** Minimum width of the split button's buttons (the touch target size). */
50
+ private const val SPLIT_MIN_WIDTH_DP = 48
51
+ }
52
+
53
+ // --- State Wrapper for Fabric state updates ---
54
+ override var stateWrapper: StateWrapper? = null
55
+
56
+ private var lastReportedWidth: Float = 0f
57
+ private var lastReportedHeight: Float = 0f
58
+
59
+ // --- Props ---
60
+ var items: List<Item> = emptyList()
61
+ var variant: PCExpressive.Variant = PCExpressive.Variant.OUTLINED
62
+ var size: String = "small"
63
+ var shape: String = "round"
64
+ var connected: Boolean = false
65
+ var spacing: Float = -1f // dp; negative = style default
66
+ var selection: String = "none" // "none" | "single" | "multiple"
67
+ var selectedValues: List<String> = emptyList()
68
+ var selectionRequired: Boolean = false
69
+ var interactivity: String = "enabled" // "enabled" | "disabled"
70
+ var overflow: String = "none" // "none" | "menu" | "wrap"
71
+ var expressive: Boolean = true // android.material: "expressive" | "m3"
72
+ var split: Boolean = false // MaterialSplitButton: the first button and a menu button
73
+ /** The split button's flattened menu items (see PCMenuSupport) */
74
+ var menuItems: List<PCMenuSupport.Item> = emptyList()
75
+ var menuAccessibilityLabel: String = ""
76
+
77
+ // --- Styling (null / empty = Material theme default) ---
78
+ var containerColor: Int? = null
79
+ var foregroundColor: Int? = null
80
+ var rippleColor: Int? = null
81
+ var strokeColor: Int? = null
82
+ var labelFontFamily: String = ""
83
+ var labelFontSize: Float = 0f
84
+ var labelFontWeight: String = ""
85
+ var labelFontStyle: String = ""
86
+
87
+ /** The `haptics` prop: the manager plays it on a press (an overflow pick included), the split menu on a pick. */
88
+ var haptics: String = ""
89
+
90
+ // --- Events ---
91
+ var onPress: ((index: Int, value: String) -> Unit)? = null
92
+ var onSelectionChange: ((values: List<String>) -> Unit)? = null
93
+ var onMenuSelect: ((id: String, title: String) -> Unit)? = null
94
+ var onMenuOpen: (() -> Unit)? = null
95
+ var onMenuClose: (() -> Unit)? = null
96
+
97
+ // --- UI ---
98
+ private var group: MaterialButtonGroup? = null
99
+ private var popupMenu: PopupMenu? = null
100
+ private val buttonIdToIndex: MutableMap<Int, Int> = mutableMapOf()
101
+ private var suppressCallbacks = false
102
+ private var selectionEmitPending = false
103
+
104
+ /** Bumped on every rebuild so late image loads can't touch stale buttons. */
105
+ private var rebuildGeneration = 0
106
+
107
+ // --- Native theme ---
108
+ private var builtThemeVersion = PCNativeTheme.version
109
+ private val nativeThemeListener = PCNativeTheme.Listener {
110
+ PCThemeSupport.clearColorStateListCaches(this)
111
+ rebuildUI()
112
+ }
113
+
114
+ init {
115
+ clipChildren = false
116
+ clipToPadding = false
117
+ rebuildUI()
118
+ }
119
+
120
+ // ---- Public apply* (called by manager) ----
121
+
122
+ fun applyItems(value: List<Item>) {
123
+ if (items == value) return
124
+ items = value
125
+ rebuildUI()
126
+ }
127
+
128
+ fun applyVariant(value: String?) {
129
+ val parsed = PCExpressive.parseVariant(value)
130
+ if (variant == parsed) return
131
+ variant = parsed
132
+ rebuildUI()
133
+ }
134
+
135
+ fun applySize(value: String?) {
136
+ val parsed = PCExpressive.parseSize(value)
137
+ if (size == parsed) return
138
+ size = parsed
139
+ rebuildUI()
140
+ }
141
+
142
+ fun applyShape(value: String?) {
143
+ val parsed = PCExpressive.parseShape(value)
144
+ if (shape == parsed) return
145
+ shape = parsed
146
+ rebuildUI()
147
+ }
148
+
149
+ fun applyConnected(value: Boolean) {
150
+ if (connected == value) return
151
+ connected = value
152
+ rebuildUI()
153
+ }
154
+
155
+ fun applySpacing(value: Float) {
156
+ if (spacing == value) return
157
+ spacing = value
158
+ rebuildUI()
159
+ }
160
+
161
+ fun applySelection(value: String?) {
162
+ val parsed = when (value) {
163
+ "single", "multiple" -> value
164
+ else -> "none"
165
+ }
166
+ if (selection == parsed) return
167
+ selection = parsed
168
+ rebuildUI()
169
+ }
170
+
171
+ fun applySelectedValues(value: List<String>) {
172
+ if (selectedValues == value) return
173
+ selectedValues = value
174
+ updateSelection()
175
+ }
176
+
177
+ fun applySelectionRequired(value: Boolean) {
178
+ if (selectionRequired == value) return
179
+ selectionRequired = value
180
+ (group as? MaterialButtonToggleGroup)?.isSelectionRequired = value
181
+ }
182
+
183
+ fun applyInteractivity(value: String?) {
184
+ val newValue = if (value == "disabled") "disabled" else "enabled"
185
+ if (interactivity == newValue) return
186
+ interactivity = newValue
187
+ updateEnabled()
188
+ }
189
+
190
+ fun applyOverflow(value: String?) {
191
+ val parsed = when (value) {
192
+ "menu", "wrap" -> value
193
+ else -> "none"
194
+ }
195
+ if (overflow == parsed) return
196
+ overflow = parsed
197
+ rebuildUI()
198
+ }
199
+
200
+ fun applySplit(value: Boolean) {
201
+ if (split == value) return
202
+ split = value
203
+ rebuildUI()
204
+ }
205
+
206
+ fun applyMenu(value: List<PCMenuSupport.Item>) {
207
+ menuItems = value
208
+ }
209
+
210
+ fun applyMenuAccessibilityLabel(value: String) {
211
+ if (menuAccessibilityLabel == value) return
212
+ menuAccessibilityLabel = value
213
+ splitMenuButton()?.contentDescription = value.ifEmpty { null }
214
+ }
215
+
216
+ fun applyMaterial(value: String?) {
217
+ val parsed = PCExpressive.parseExpressive(value)
218
+ if (expressive == parsed) return
219
+ expressive = parsed
220
+ rebuildUI()
221
+ }
222
+
223
+ fun applyColors(container: Int?, foreground: Int?, ripple: Int?, stroke: Int?) {
224
+ if (containerColor == container && foregroundColor == foreground &&
225
+ rippleColor == ripple && strokeColor == stroke
226
+ ) return
227
+ containerColor = container
228
+ foregroundColor = foreground
229
+ rippleColor = ripple
230
+ strokeColor = stroke
231
+ rebuildUI()
232
+ }
233
+
234
+ fun applyLabelStyle(fontFamily: String, fontSize: Float, fontWeight: String, fontStyle: String) {
235
+ if (labelFontFamily == fontFamily && labelFontSize == fontSize &&
236
+ labelFontWeight == fontWeight && labelFontStyle == fontStyle
237
+ ) return
238
+ labelFontFamily = fontFamily
239
+ labelFontSize = fontSize
240
+ labelFontWeight = fontWeight
241
+ labelFontStyle = fontStyle
242
+ rebuildUI()
243
+ }
244
+
245
+ // The buttons have generated view ids, which React Native's touch handling would
246
+ // take for React tags and dispatch JS touch events to unrelated views. Claim the
247
+ // touch for this view instead; the buttons still receive it natively.
248
+ override fun interceptsTouchEvent(touchX: Float, touchY: Float): Boolean = true
249
+
250
+ override fun reactTagForTouch(touchX: Float, touchY: Float): Int = id
251
+
252
+ override fun onAttachedToWindow() {
253
+ super.onAttachedToWindow()
254
+ PCNativeTheme.addListener(nativeThemeListener)
255
+ PCNativeTheme.attach(context)
256
+ if (builtThemeVersion != PCNativeTheme.version) nativeThemeListener.onNativeThemeChanged()
257
+ }
258
+
259
+ override fun onDetachedFromWindow() {
260
+ PCNativeTheme.removeListener(nativeThemeListener)
261
+ popupMenu?.dismiss()
262
+ super.onDetachedFromWindow()
263
+ }
264
+
265
+ // ---- UI Building ----
266
+
267
+ private fun rebuildUI() {
268
+ builtThemeVersion = PCNativeTheme.version
269
+ removeAllViews()
270
+ buttonIdToIndex.clear()
271
+ rebuildGeneration += 1
272
+ val generation = rebuildGeneration
273
+
274
+ // Material widgets need a Material theme; fall back to Material 3 defaults instead of crashing.
275
+ val base = PCThemeSupport.materialContext(context, "ButtonGroup")
276
+ val toggle = selection != "none"
277
+
278
+ // The group styles: a standard group (spacing, press size morph) or a
279
+ // connected one (shared outline, small inner corners), Expressive or
280
+ // classic Material 3.
281
+ val overlay = when {
282
+ expressive && toggle && !connected -> R.style.PCExpressiveOverlay_StandardToggleGroup
283
+ expressive && !toggle && connected -> R.style.PCExpressiveOverlay_ConnectedGroup
284
+ expressive -> R.style.PCExpressiveOverlay
285
+ toggle && !connected -> R.style.PCM3Overlay_StandardToggleGroup
286
+ !toggle && connected -> R.style.PCM3Overlay_ConnectedGroup
287
+ else -> 0
288
+ }
289
+ val groupContext = if (overlay != 0) ContextThemeWrapper(base, overlay) else base
290
+
291
+ val g: MaterialButtonGroup =
292
+ if (split) {
293
+ // Material's split button style (a small gap and inner corners that
294
+ // round while the menu is open) over the Expressive widget styles
295
+ MaterialSplitButton(if (expressive) ContextThemeWrapper(base, R.style.PCExpressiveOverlay) else base).apply {
296
+ // Laid out like the other groups, without the style's vertical padding
297
+ setPadding(0, 0, 0, 0)
298
+ }
299
+ } else if (toggle) {
300
+ MaterialButtonToggleGroup(groupContext).apply {
301
+ isSingleSelection = selection == "single"
302
+ isSelectionRequired = selectionRequired
303
+ }
304
+ } else {
305
+ MaterialButtonGroup(groupContext)
306
+ }
307
+ g.layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
308
+ g.clipChildren = false
309
+ g.clipToPadding = false
310
+ if (spacing >= 0) {
311
+ g.spacing = (spacing * resources.displayMetrics.density).toInt()
312
+ }
313
+ g.overflowMode = when (overflow) {
314
+ "menu" -> if (split) MaterialButtonGroup.OVERFLOW_MODE_NONE else MaterialButtonGroup.OVERFLOW_MODE_MENU
315
+ "wrap" -> if (split) MaterialButtonGroup.OVERFLOW_MODE_NONE else MaterialButtonGroup.OVERFLOW_MODE_WRAP
316
+ else -> MaterialButtonGroup.OVERFLOW_MODE_NONE
317
+ }
318
+
319
+ // A split button is one button and its menu button
320
+ val shown = if (split) items.take(1) else items
321
+ for ((index, item) in shown.withIndex()) {
322
+ val iconOnly = item.label.isEmpty() && item.icon.isPresent
323
+
324
+ val button = PCExpressive.createButton(
325
+ base, variant, size, shape, iconOnly, 0, expressive
326
+ ).apply {
327
+ id = View.generateViewId()
328
+ text = item.label
329
+ isAllCaps = false // Preserve original text casing
330
+ ellipsize = TextUtils.TruncateAt.END
331
+ maxLines = 1
332
+ contentDescription = item.spokenLabel.ifEmpty { null }
333
+ isEnabled = !item.disabled && interactivity == "enabled"
334
+ if (iconOnly) {
335
+ // Centre the icon instead of leaving it at the start edge
336
+ iconGravity = MaterialButton.ICON_GRAVITY_TEXT_START
337
+ }
338
+ setOnClickListener { onPress?.invoke(index, item.value) }
339
+ }
340
+
341
+ PCButtonSupport.applyIcon(button, item.icon, { generation == rebuildGeneration }) { requestLayout() }
342
+ PCButtonSupport.applyFont(button, labelFontFamily, labelFontSize, labelFontWeight, labelFontStyle)
343
+ PCButtonSupport.applyColors(button, containerColor, foregroundColor, rippleColor, strokeColor, item.icon.tinted)
344
+
345
+ buttonIdToIndex[button.id] = index
346
+ // Buttons size to their content. Connected buttons also share any extra
347
+ // width when the group is stretched (and any shortfall when it is
348
+ // squeezed) equally; standard buttons keep their own width.
349
+ val params = MaterialButtonGroup.LayoutParams(
350
+ LayoutParams.WRAP_CONTENT,
351
+ LayoutParams.WRAP_CONTENT,
352
+ if (connected) 1f else 0f
353
+ )
354
+ params.overflowText = item.spokenLabel
355
+ g.addView(button, params)
356
+ }
357
+
358
+ if (split && shown.isNotEmpty()) addSplitMenuButton(g as MaterialSplitButton, base, g.getChildAt(0) as MaterialButton)
359
+
360
+ if (g is MaterialButtonToggleGroup) {
361
+ g.addOnButtonCheckedListener { _, _, _ ->
362
+ if (suppressCallbacks) return@addOnButtonCheckedListener
363
+ // A single-selection switch reports the old button unchecked and the
364
+ // new one checked in turn; report the final selection once.
365
+ scheduleSelectionEmit()
366
+ }
367
+ }
368
+
369
+ addView(g)
370
+ group = g
371
+
372
+ updateSelection()
373
+ updateEnabled()
374
+ requestLayout()
375
+ }
376
+
377
+ // ---- Split button ----
378
+
379
+ /**
380
+ * The trailing button of a split button: Material's chevron in a button of
381
+ * the leading button's style, which MaterialSplitButton makes checkable.
382
+ * Checking it opens the menu and turns the chevron; closing the menu
383
+ * unchecks it. It keeps the leading button's colors while checked, as
384
+ * Material's split button styles do, so only the chevron and the inner
385
+ * corners change.
386
+ */
387
+ private fun addSplitMenuButton(g: MaterialSplitButton, base: Context, leading: MaterialButton) {
388
+ val metrics = splitMetrics(if (expressive) size else "small")
389
+ val density = resources.displayMetrics.density
390
+ fun dp(value: Int) = (value * density).toInt()
391
+
392
+ val menuButton = PCExpressive.createButton(base, variant, size, "round", false, 0, expressive).apply {
393
+ id = View.generateViewId()
394
+ icon = ContextCompat.getDrawable(context, MaterialR.drawable.m3_split_button_chevron_avd)
395
+ iconSize = dp(metrics.iconSize)
396
+ iconPadding = 0
397
+ iconGravity = MaterialButton.ICON_GRAVITY_TEXT_START
398
+ setPaddingRelative(dp(metrics.menuStart), paddingTop, dp(metrics.menuEnd), paddingBottom)
399
+ // The touch target size, as Material's split button styles set, in
400
+ // place of the button styles' minimum width
401
+ minWidth = dp(SPLIT_MIN_WIDTH_DP)
402
+ minimumWidth = dp(SPLIT_MIN_WIDTH_DP)
403
+ contentDescription = menuAccessibilityLabel.ifEmpty { null }
404
+ isEnabled = interactivity == "enabled"
405
+ }
406
+ leading.setPaddingRelative(dp(metrics.leadingStart), leading.paddingTop, dp(metrics.leadingEnd), leading.paddingBottom)
407
+ leading.minWidth = dp(SPLIT_MIN_WIDTH_DP)
408
+ leading.minimumWidth = dp(SPLIT_MIN_WIDTH_DP)
409
+
410
+ g.addView(menuButton, MaterialButtonGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0f))
411
+ menuButton.backgroundTintList = uncheckable(leading.backgroundTintList)
412
+ menuButton.iconTint = uncheckable(leading.iconTint ?: leading.textColors)
413
+ menuButton.strokeColor = uncheckable(leading.strokeColor)
414
+ menuButton.strokeWidth = leading.strokeWidth
415
+ menuButton.rippleColor = leading.rippleColor
416
+ menuButton.addOnCheckedChangeListener { button, checked -> if (checked) showSplitMenu(button) }
417
+ }
418
+
419
+ /**
420
+ * A button's enabled and disabled colors, without the checked states the
421
+ * Material toggle colors add, so a checkable button keeps them.
422
+ */
423
+ private fun uncheckable(colors: ColorStateList?): ColorStateList? {
424
+ colors ?: return null
425
+ val disabled = intArrayOf(-android.R.attr.state_enabled)
426
+ return ColorStateList(
427
+ arrayOf(disabled, intArrayOf()),
428
+ intArrayOf(
429
+ colors.getColorForState(disabled, colors.defaultColor),
430
+ colors.getColorForState(intArrayOf(android.R.attr.state_enabled), colors.defaultColor)
431
+ )
432
+ )
433
+ }
434
+
435
+ private fun splitMenuButton(): MaterialButton? =
436
+ (group as? MaterialSplitButton)?.getChildAt(1) as? MaterialButton
437
+
438
+ /** Spacing and icon size of the split button sizes, in dp (Material 1.14 tokens). */
439
+ private data class SplitMetrics(
440
+ val leadingStart: Int,
441
+ val leadingEnd: Int,
442
+ val iconSize: Int,
443
+ val menuStart: Int,
444
+ val menuEnd: Int
445
+ )
446
+
447
+ private fun splitMetrics(size: String): SplitMetrics = when (size) {
448
+ "xsmall" -> SplitMetrics(12, 10, 22, 13, 13)
449
+ "medium" -> SplitMetrics(24, 24, 26, 15, 15)
450
+ "large" -> SplitMetrics(48, 48, 38, 29, 29)
451
+ "xlarge" -> SplitMetrics(64, 64, 50, 43, 43)
452
+ else -> SplitMetrics(16, 12, 22, 13, 13)
453
+ }
454
+
455
+ /** A PopupMenu anchored to the menu button, built like ContextMenu's. */
456
+ private fun showSplitMenu(anchor: MaterialButton) {
457
+ if (popupMenu != null) return
458
+ val items = menuItems
459
+ // Aligned to the split button's end edge
460
+ val popup = PopupMenu(context, anchor, Gravity.END)
461
+ popupMenu = popup
462
+ val hasIcons = PCMenuSupport.populate(context, popup.menu, items) { popupMenu === popup }
463
+ popup.setForceShowIcon(hasIcons)
464
+
465
+ popup.setOnMenuItemClickListener { menuItem ->
466
+ // Submenu headers open their submenu; they aren't picks
467
+ val item = PCMenuSupport.itemFor(menuItem, items)
468
+ if (item == null || !item.isAction) return@setOnMenuItemClickListener false
469
+ PCHaptics.perform(this, item.haptics.ifEmpty { haptics })
470
+ onMenuSelect?.invoke(item.id, item.title)
471
+ true
472
+ }
473
+ popup.setOnDismissListener {
474
+ if (popupMenu === popup) popupMenu = null
475
+ // Turns the chevron back
476
+ anchor.isChecked = false
477
+ onMenuClose?.invoke()
478
+ }
479
+
480
+ onMenuOpen?.invoke()
481
+ popup.show()
482
+ }
483
+
484
+ private fun scheduleSelectionEmit() {
485
+ if (selectionEmitPending) return
486
+ selectionEmitPending = true
487
+ post {
488
+ selectionEmitPending = false
489
+ emitSelection()
490
+ }
491
+ }
492
+
493
+ private fun emitSelection() {
494
+ val g = group as? MaterialButtonToggleGroup ?: return
495
+ val values = g.checkedButtonIds
496
+ .mapNotNull { buttonIdToIndex[it] }
497
+ .sorted()
498
+ .map { items[it].value }
499
+ onSelectionChange?.invoke(values)
500
+ // Keep the prop authoritative even when the parent declines the edit and
501
+ // React therefore has no changed selection prop to send back.
502
+ updateSelection()
503
+ }
504
+
505
+ private fun updateSelection() {
506
+ val g = group as? MaterialButtonToggleGroup ?: return
507
+ suppressCallbacks = true
508
+ val selectedIds = buttonIdToIndex.filterValues { selectedValues.contains(items[it].value) }.keys
509
+ if (selectedIds.isEmpty()) {
510
+ // clearChecked also permits a controlled empty selection when user
511
+ // deselection is disabled by selectionRequired.
512
+ g.clearChecked()
513
+ } else {
514
+ // Check first so selectionRequired does not retain the previous last item.
515
+ selectedIds.forEach { g.check(it) }
516
+ for (id in buttonIdToIndex.keys) if (id !in selectedIds) g.uncheck(id)
517
+ }
518
+ suppressCallbacks = false
519
+ }
520
+
521
+ private fun updateEnabled() {
522
+ val enabled = interactivity == "enabled"
523
+ alpha = if (enabled) 1f else 0.5f
524
+
525
+ val g = group ?: return
526
+ for (i in 0 until g.childCount) {
527
+ val button = g.getChildAt(i) as? MaterialButton ?: continue
528
+ val index = buttonIdToIndex[button.id] ?: continue
529
+ button.isEnabled = enabled && !items[index].disabled
530
+ }
531
+ splitMenuButton()?.isEnabled = enabled
532
+ }
533
+
534
+ // ---- Layout ----
535
+
536
+ private var manualLayoutPending = false
537
+
538
+ /**
539
+ * React Native's root view ignores requestLayout after the initial pass, so
540
+ * a native view that changes its own subtree later has to measure and lay
541
+ * itself out. Coalesced to one pass per frame.
542
+ */
543
+ override fun requestLayout() {
544
+ super.requestLayout()
545
+ if (!manualLayoutPending) {
546
+ manualLayoutPending = true
547
+ post { runManualLayout() }
548
+ }
549
+ }
550
+
551
+ private fun runManualLayout() {
552
+ manualLayoutPending = false
553
+ // Nothing to do until Yoga has placed us; the regular pass covers that.
554
+ if (width == 0 || height == 0) return
555
+ measure(
556
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
557
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
558
+ )
559
+ layout(left, top, right, bottom)
560
+ }
561
+
562
+ // ---- Measurement ----
563
+
564
+ private val unspecified = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
565
+
566
+ /**
567
+ * The group's natural width: every button on one row. MaterialButtonGroup
568
+ * answers that itself, except in the "wrap" overflow mode, which refuses an
569
+ * AT_MOST width and lays every button on its own row for UNSPECIFIED; there
570
+ * the buttons are summed instead.
571
+ */
572
+ private fun naturalWidth(child: MaterialButtonGroup): Int {
573
+ if (overflow != "wrap") {
574
+ child.measure(unspecified, unspecified)
575
+ return child.measuredWidth
576
+ }
577
+ var total = child.paddingLeft + child.paddingRight
578
+ var visible = 0
579
+ for (i in 0 until child.childCount) {
580
+ val button = child.getChildAt(i)
581
+ if (button.visibility == View.GONE) continue
582
+ button.measure(unspecified, unspecified)
583
+ val params = button.layoutParams as? MarginLayoutParams
584
+ total += button.measuredWidth + (params?.leftMargin ?: 0) + (params?.rightMargin ?: 0)
585
+ visible++
586
+ }
587
+ if (visible > 1) total += child.spacing * (visible - 1)
588
+ return total
589
+ }
590
+
591
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
592
+ val child = group
593
+ if (child == null) {
594
+ setMeasuredDimension(0, 0)
595
+ return
596
+ }
597
+
598
+ val natural = naturalWidth(child)
599
+ val width = resolveDimension(widthMeasureSpec, natural)
600
+ child.measure(MeasureSpec.makeMeasureSpec(minOf(width, natural), MeasureSpec.EXACTLY), unspecified)
601
+ val height = resolveDimension(heightMeasureSpec, child.measuredHeight)
602
+
603
+ child.measure(
604
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
605
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
606
+ )
607
+ setMeasuredDimension(width, height)
608
+ }
609
+
610
+ private fun resolveDimension(spec: Int, desired: Int): Int {
611
+ val size = MeasureSpec.getSize(spec)
612
+ return when (MeasureSpec.getMode(spec)) {
613
+ // Fabric may give us 0 before the state is applied; keep the natural size then.
614
+ MeasureSpec.EXACTLY -> if (size > 0) size else desired
615
+ MeasureSpec.AT_MOST -> minOf(desired, size)
616
+ else -> desired
617
+ }
618
+ }
619
+
620
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
621
+ super.onLayout(changed, left, top, right, bottom)
622
+ updateFrameSizeState()
623
+ }
624
+
625
+ /** Reports the intrinsic size to Fabric; called as soon as the state wrapper is available. */
626
+ fun reportIntrinsicSize() = updateFrameSizeState()
627
+
628
+ /**
629
+ * Update Fabric state with the group's natural size, so the shadow node
630
+ * wraps its content in Yoga layout.
631
+ */
632
+ private fun updateFrameSizeState() {
633
+ val wrapper = stateWrapper ?: return
634
+ val child = group ?: return
635
+
636
+ // The natural width, and the height at the width we actually have when
637
+ // that is narrower (an overflow "wrap" group grows taller then).
638
+ val naturalWidth = naturalWidth(child)
639
+ val fittedWidth = if (width in 1 until naturalWidth) width else naturalWidth
640
+ child.measure(MeasureSpec.makeMeasureSpec(fittedWidth, MeasureSpec.EXACTLY), unspecified)
641
+ val widthDp = PixelUtil.toDIPFromPixel(naturalWidth.toFloat())
642
+ val heightDp = PixelUtil.toDIPFromPixel(child.measuredHeight.toFloat())
643
+
644
+ // Measuring re-wraps the labels; restore the laid-out size so they are
645
+ // ellipsized to the bounds they are drawn in.
646
+ if (child.width > 0 && child.height > 0) {
647
+ child.measure(
648
+ MeasureSpec.makeMeasureSpec(child.width, MeasureSpec.EXACTLY),
649
+ MeasureSpec.makeMeasureSpec(child.height, MeasureSpec.EXACTLY)
650
+ )
651
+ }
652
+
653
+ if (widthDp != lastReportedWidth || heightDp != lastReportedHeight) {
654
+ lastReportedWidth = widthDp
655
+ lastReportedHeight = heightDp
656
+
657
+ val stateData = WritableNativeMap().apply {
658
+ putDouble("width", widthDp.toDouble())
659
+ putDouble("height", heightDp.toDouble())
660
+ }
661
+ wrapper.updateState(stateData)
662
+ }
663
+ }
664
+ }