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
@@ -2,6 +2,9 @@ import UIKit
2
2
 
3
3
  /// A row of native buttons (`UIButton` with configurations), with optional
4
4
  /// single / multiple selection shown through the buttons' selected state.
5
+ /// Buttons that don't fit can fold into a "…" button with a `UIMenu`
6
+ /// (overflow "menu"). In split mode the row is one button joined to a
7
+ /// chevron button that opens a `UIMenu` (SplitButton).
5
8
  @objcMembers
6
9
  public final class PCButtonGroupView: UIView {
7
10
  private struct Item {
@@ -78,10 +81,46 @@ public final class PCButtonGroupView: UIView {
78
81
  didSet { applyConfigurations() }
79
82
  }
80
83
 
84
+ /// "none" | "menu" | "wrap" (Android only; the same as "none" here)
85
+ public var overflow: String = "none" {
86
+ didSet {
87
+ guard oldValue != overflow else { return }
88
+ overflowDirty = true
89
+ invalidateIntrinsicContentSize()
90
+ setNeedsLayout()
91
+ }
92
+ }
93
+
94
+ /// Split mode: the first button joined to a chevron button with `menu`.
95
+ public var split: Bool = false {
96
+ didSet { if oldValue != split { rebuild() } }
97
+ }
98
+
99
+ /// ObjC++ sets this as an array of dictionaries: the split button's
100
+ /// flattened menu items
101
+ public var menuItems: [Any] = [] {
102
+ didSet {
103
+ splitItems = PCMenuSupport.items(from: menuItems)
104
+ updateSplitMenu()
105
+ }
106
+ }
107
+
108
+ /// What VoiceOver announces for the split button's chevron.
109
+ public var menuAccessibilityLabel: String = "" {
110
+ didSet { chevronButton?.accessibilityLabel = menuAccessibilityLabel.isEmpty ? nil : menuAccessibilityLabel }
111
+ }
112
+
113
+ /// The `haptics` prop: PCButtonGroup.mm plays it on a press (an overflow
114
+ /// pick included), the split menu handler on a pick
115
+ public let haptics = PCHaptics()
116
+
81
117
  // MARK: - Events back to ObjC++
82
118
 
83
119
  public var onPress: ((Int, String) -> Void)? // (index, value)
84
120
  public var onSelectionChange: (([String]) -> Void)?
121
+ public var onMenuSelect: ((String, String) -> Void)? // (id, title)
122
+ public var onMenuOpen: (() -> Void)?
123
+ public var onMenuClose: (() -> Void)?
85
124
 
86
125
  /// Called when content changed after layout (an icon finished loading),
87
126
  /// so the Fabric measurement can be refreshed.
@@ -94,6 +133,20 @@ public final class PCButtonGroupView: UIView {
94
133
  private var uiButtons: [UIButton] = []
95
134
  private var iconImages: [UIImage?] = []
96
135
 
136
+ /// Split mode: the chevron button after the button, and its menu items.
137
+ private var chevronButton: PCMenuButton?
138
+ private var splitItems: [PCMenuItem] = []
139
+ private let splitMenuImages = PCMenuImageState()
140
+ private let overflowMenuImages = PCMenuImageState()
141
+
142
+ /// Overflow "menu": the "…" button that holds the buttons that don't
143
+ /// fit (made the first time it is needed), and how many buttons are
144
+ /// showing (all of them when nil).
145
+ private var overflowButton: PCMenuButton?
146
+ private var visibleCount: Int?
147
+ /// Set when the buttons changed, so the next layout folds them again.
148
+ private var overflowDirty = true
149
+
97
150
  /// Bumped on every rebuild so late image loads can't touch stale buttons.
98
151
  private var rebuildGeneration = 0
99
152
 
@@ -144,13 +197,23 @@ public final class PCButtonGroupView: UIView {
144
197
 
145
198
  uiButtons.forEach { $0.removeFromSuperview() }
146
199
  uiButtons = []
200
+ chevronButton?.removeFromSuperview()
201
+ chevronButton = nil
202
+ visibleCount = nil
203
+ overflowButton?.isHidden = true
204
+ overflowDirty = true
205
+ // A split button is one button and its chevron
206
+ if split && items.count > 1 { items = Array(items.prefix(1)) }
207
+ overflowMenuImages.retain(icons: items.map(\.icon))
147
208
  iconImages = Array(repeating: nil, count: items.count)
148
209
 
149
210
  for (index, item) in items.enumerated() {
150
211
  let button = UIButton(type: .system)
151
212
  button.tag = index
152
213
  button.addTarget(self, action: #selector(tapped(_:)), for: .touchUpInside)
153
- stack.addArrangedSubview(button)
214
+ button.addTarget(self, action: #selector(touchedDown), for: .touchDown)
215
+ // Before the overflow button, which stays last
216
+ stack.insertArrangedSubview(button, at: index)
154
217
  uiButtons.append(button)
155
218
 
156
219
  iconImages[index] = PCButtonSupport.image(for: item.icon) { [weak self] image in
@@ -161,8 +224,19 @@ public final class PCButtonGroupView: UIView {
161
224
  }
162
225
  }
163
226
 
227
+ if split {
228
+ let chevron = PCMenuButton(type: .system)
229
+ chevron.accessibilityLabel = menuAccessibilityLabel.isEmpty ? nil : menuAccessibilityLabel
230
+ chevron.onMenuOpen = { [weak self] in self?.onMenuOpen?() }
231
+ chevron.onMenuClose = { [weak self] in self?.onMenuClose?() }
232
+ stack.insertArrangedSubview(chevron, at: items.count)
233
+ chevronButton = chevron
234
+ updateSplitMenu()
235
+ }
236
+
164
237
  applyConfigurations()
165
238
  updateEnabled()
239
+ setNeedsLayout()
166
240
  }
167
241
 
168
242
  private func applyLayout() {
@@ -191,7 +265,11 @@ public final class PCButtonGroupView: UIView {
191
265
  )
192
266
  button.accessibilityLabel = item.spokenLabel.isEmpty ? nil : item.spokenLabel
193
267
  }
268
+ if let chevron = chevronButton { configureSymbolButton(chevron, symbol: "chevron.down") }
269
+ if let more = overflowButton { configureSymbolButton(more, symbol: "ellipsis") }
270
+ overflowDirty = true
194
271
  invalidateIntrinsicContentSize()
272
+ setNeedsLayout()
195
273
  }
196
274
 
197
275
  private func updateEnabled() {
@@ -200,18 +278,148 @@ public final class PCButtonGroupView: UIView {
200
278
  for (index, button) in uiButtons.enumerated() where index < items.count {
201
279
  button.isEnabled = enabled && !items[index].disabled
202
280
  }
281
+ chevronButton?.isEnabled = enabled
282
+ overflowButton?.isEnabled = enabled
283
+ updateOverflowMenu()
284
+ }
285
+
286
+ /// The chevron and "…" buttons take the variant of the buttons.
287
+ private func configureSymbolButton(_ button: UIButton, symbol: String) {
288
+ button.configuration = PCButtonSupport.makeConfiguration(
289
+ variant: variant,
290
+ selected: false,
291
+ size: size,
292
+ shape: shape,
293
+ label: "",
294
+ image: UIImage(systemName: symbol),
295
+ containerColor: containerColor,
296
+ foregroundColor: foregroundColor,
297
+ font: labelFont
298
+ )
299
+ }
300
+
301
+ // MARK: - Split menu
302
+
303
+ private func updateSplitMenu() {
304
+ splitMenuImages.retain(icons: splitItems.map(\.icon))
305
+ guard let chevron = chevronButton else { return }
306
+ chevron.setMenu(splitItems.isEmpty ? nil : PCMenuSupport.menu(
307
+ title: "",
308
+ items: splitItems,
309
+ imageState: splitMenuImages,
310
+ onImageLoaded: { [weak self] in self?.updateSplitMenu() },
311
+ handler: { [weak self] item in
312
+ guard let self else { return }
313
+ self.haptics.perform(in: self, override: item.haptics)
314
+ self.onMenuSelect?(item.id, item.title)
315
+ }
316
+ ))
317
+ }
318
+
319
+ // MARK: - Overflow
320
+
321
+ /// Folds the trailing buttons that don't fit into the "…" button, which
322
+ /// takes their place at the end of the row.
323
+ public override func layoutSubviews() {
324
+ updateOverflow()
325
+ super.layoutSubviews()
326
+ }
327
+
328
+ private func updateOverflow() {
329
+ let count: Int? = overflow == "menu" && !split && bounds.width > 0 ? fittingCount() : nil
330
+ guard overflowDirty || count != visibleCount else { return }
331
+ overflowDirty = false
332
+ visibleCount = count
333
+ for (index, button) in uiButtons.enumerated() {
334
+ button.isHidden = count.map { index >= $0 } ?? false
335
+ }
336
+ if count != nil {
337
+ makeOverflowButton().isHidden = false
338
+ } else {
339
+ overflowButton?.isHidden = true
340
+ }
341
+ updateOverflowMenu()
342
+ }
343
+
344
+ /// The "…" button, at the end of the row. The ellipsis symbol reads as
345
+ /// "More" in VoiceOver.
346
+ private func makeOverflowButton() -> PCMenuButton {
347
+ if let button = overflowButton { return button }
348
+ let button = PCMenuButton(type: .system)
349
+ button.isHidden = true
350
+ button.isEnabled = interactivity != "disabled"
351
+ configureSymbolButton(button, symbol: "ellipsis")
352
+ stack.addArrangedSubview(button)
353
+ overflowButton = button
354
+ return button
355
+ }
356
+
357
+ /// How many buttons fit before the "…" button, or nil when all of them
358
+ /// fit.
359
+ private func fittingCount() -> Int? {
360
+ let widths = uiButtons.map { $0.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).width }
361
+ let gap = stack.spacing
362
+ let all = widths.reduce(0, +) + gap * CGFloat(max(widths.count - 1, 0))
363
+ guard all > bounds.width + 0.5 else { return nil }
364
+ var used = makeOverflowButton().systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).width
365
+ var count = 0
366
+ for width in widths {
367
+ guard used + gap + width <= bounds.width + 0.5 else { break }
368
+ used += gap + width
369
+ count += 1
370
+ }
371
+ return count
372
+ }
373
+
374
+ /// The "…" button's menu: the hidden buttons, with their icons, disabled
375
+ /// state and selection checkmark. A pick acts like a press.
376
+ private func updateOverflowMenu() {
377
+ guard let overflowButton else { return }
378
+ guard let count = visibleCount else {
379
+ overflowMenuImages.retain(icons: [])
380
+ overflowButton.setMenu(nil)
381
+ return
382
+ }
383
+ let enabled = interactivity != "disabled"
384
+ let hidden = items.enumerated().dropFirst(count).map { index, item in
385
+ PCMenuItem(
386
+ index: index,
387
+ id: item.value,
388
+ title: item.label.isEmpty ? item.accessibilityLabel : item.label,
389
+ icon: item.icon,
390
+ disabled: !enabled || item.disabled,
391
+ state: selection != "none" && selectedValues.contains(item.value) ? "on" : ""
392
+ )
393
+ }
394
+ overflowButton.setMenu(PCMenuSupport.menu(
395
+ title: "",
396
+ items: hidden,
397
+ imageState: overflowMenuImages,
398
+ onImageLoaded: { [weak self] in self?.updateOverflowMenu() },
399
+ handler: { [weak self] item in self?.press(at: item.index) }
400
+ ))
203
401
  }
204
402
 
205
403
  // MARK: - Selection
206
404
 
405
+ /// Readies the haptic for the press that is likely to follow.
406
+ @objc private func touchedDown() {
407
+ haptics.prepare(in: self)
408
+ }
409
+
207
410
  @objc private func tapped(_ sender: UIButton) {
208
- let index = sender.tag
411
+ press(at: sender.tag)
412
+ }
413
+
414
+ /// A press on a button, or a pick of its overflow menu item.
415
+ private func press(at index: Int) {
209
416
  guard index >= 0, index < items.count else { return }
210
417
  let item = items[index]
211
418
  onPress?(index, item.value)
212
419
 
213
420
  guard selection != "none", let next = nextSelection(tapping: item.value) else { return }
214
- selectedValues = next
421
+ // The parent owns selection. A rejected change must leave the
422
+ // existing buttons (and overflow checkmarks) selected.
215
423
  onSelectionChange?(next)
216
424
  }
217
425
 
@@ -238,17 +446,28 @@ public final class PCButtonGroupView: UIView {
238
446
 
239
447
  // MARK: - Sizing
240
448
 
449
+ /// The row with every button showing: an overflowing group reports its
450
+ /// full width, and Yoga clamps it to the space there is.
451
+ private func naturalSize() -> CGSize {
452
+ guard visibleCount != nil else {
453
+ return stack.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
454
+ }
455
+ let sizes = uiButtons.map { $0.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) }
456
+ let width = sizes.map(\.width).reduce(0, +) + stack.spacing * CGFloat(max(sizes.count - 1, 0))
457
+ return CGSize(width: width, height: sizes.map(\.height).max() ?? 0)
458
+ }
459
+
241
460
  public override var intrinsicContentSize: CGSize {
242
- stack.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
461
+ naturalSize()
243
462
  }
244
463
 
245
464
  public override func sizeThatFits(_ size: CGSize) -> CGSize {
246
- stack.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
465
+ naturalSize()
247
466
  }
248
467
 
249
468
  /// Called by the measuring pipeline to get the size for Yoga layout.
250
469
  @objc public func sizeForLayout(withConstrainedTo constrainedSize: CGSize) -> CGSize {
251
- let fitted = stack.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
470
+ let fitted = naturalSize()
252
471
  return CGSize(width: ceil(fitted.width), height: ceil(fitted.height))
253
472
  }
254
473
  }
@@ -1,15 +1,17 @@
1
+ import Symbols
1
2
  import UIKit
2
3
 
3
4
  /// UIButton configuration and icon handling shared by PCButtonView and
4
5
  /// PCButtonGroupView.
5
6
  enum PCButtonSupport {
6
- struct Icon: Equatable {
7
+ struct Icon: Hashable {
7
8
  /// "", "sfSymbol", "drawable" (ignored on iOS) or "image"
8
9
  var type: String = ""
9
10
  var name: String = ""
10
11
  var uri: String = ""
11
12
  var scale: CGFloat = 1
12
13
  var tinted: Bool = true
14
+ var request: String = ""
13
15
 
14
16
  var isPresent: Bool { type == "sfSymbol" || type == "image" }
15
17
 
@@ -17,12 +19,13 @@ enum PCButtonSupport {
17
19
 
18
20
  init() {}
19
21
 
20
- init(type: String, name: String, uri: String, scale: CGFloat, tinted: Bool) {
22
+ init(type: String, name: String, uri: String, scale: CGFloat, tinted: Bool, request: String = "") {
21
23
  self.type = type
22
24
  self.name = name
23
25
  self.uri = uri
24
26
  self.scale = scale > 0 ? scale : 1
25
27
  self.tinted = tinted
28
+ self.request = request
26
29
  }
27
30
 
28
31
  /// Reads the flat icon fields (iconType, iconName, ...) bridged as a dictionary.
@@ -33,7 +36,8 @@ enum PCButtonSupport {
33
36
  name: (dictionary["iconName"] as? String) ?? "",
34
37
  uri: (dictionary["iconUri"] as? String) ?? "",
35
38
  scale: scale,
36
- tinted: (dictionary["iconTinted"] as? String) != "false"
39
+ tinted: (dictionary["iconTinted"] as? String) != "false",
40
+ request: (dictionary["iconRequest"] as? String) ?? ""
37
41
  )
38
42
  }
39
43
  }
@@ -48,17 +52,81 @@ enum PCButtonSupport {
48
52
  /// | outlined | .bordered() |
49
53
  /// | text | .plain() |
50
54
  /// | elevated | .gray() |
55
+ /// | glass | .glass() on iOS 26+, .gray() before |
56
+ /// | prominentGlass | .prominentGlass() on iOS 26+, .filled() before |
57
+ /// | clearGlass | .clearGlass() on iOS 26+, .gray() before |
58
+ /// | prominentClearGlass | .prominentClearGlass() on iOS 26+, .filled() before |
59
+ ///
60
+ /// Selected glass buttons, clear or not, use the prominent glass style.
51
61
  static func configuration(variant: String, selected: Bool) -> UIButton.Configuration {
52
- if selected { return .filled() }
62
+ if selected {
63
+ switch variant {
64
+ // Prominent clear glass has no tint unless given a color, so a
65
+ // selected clear glass button takes the prominent glass too
66
+ case "glass", "prominentGlass", "clearGlass", "prominentClearGlass": return prominentGlass()
67
+ default: return .filled()
68
+ }
69
+ }
53
70
  switch variant {
54
71
  case "tonal": return .tinted()
55
72
  case "outlined": return .bordered()
56
73
  case "text": return .plain()
57
74
  case "elevated": return .gray()
75
+ case "glass": return glassConfiguration()
76
+ case "prominentGlass": return prominentGlass()
77
+ case "clearGlass": return clearGlass()
78
+ case "prominentClearGlass": return prominentClearGlass()
58
79
  default: return .filled()
59
80
  }
60
81
  }
61
82
 
83
+ /// The variant a toggle button shows. UIKit gives most configurations a
84
+ /// selected look of their own (tinted becomes filled; bordered, plain,
85
+ /// gray and glass become tinted), but none for the prominent styles and
86
+ /// clear glass. Those toggles show a quieter style while off (filled is
87
+ /// gray, prominent glass is glass), and clear glass takes the prominent
88
+ /// glass while on.
89
+ static func toggleVariant(_ variant: String, selected: Bool) -> String {
90
+ switch variant {
91
+ case "filled": return selected ? "filled" : "elevated"
92
+ case "prominentGlass": return selected ? "prominentGlass" : "glass"
93
+ case "clearGlass", "prominentClearGlass": return selected ? "prominentGlass" : "clearGlass"
94
+ default: return variant
95
+ }
96
+ }
97
+
98
+ /// `.glass()` needs the iOS 26 SDK and runtime; `.gray()` otherwise.
99
+ private static func glassConfiguration() -> UIButton.Configuration {
100
+ #if compiler(>=6.2)
101
+ if #available(iOS 26.0, *) { return .glass() }
102
+ #endif
103
+ return .gray()
104
+ }
105
+
106
+ /// `.prominentGlass()` needs the iOS 26 SDK and runtime; `.filled()` otherwise.
107
+ private static func prominentGlass() -> UIButton.Configuration {
108
+ #if compiler(>=6.2)
109
+ if #available(iOS 26.0, *) { return .prominentGlass() }
110
+ #endif
111
+ return .filled()
112
+ }
113
+
114
+ /// `.clearGlass()` needs the iOS 26 SDK and runtime; `.gray()` otherwise.
115
+ private static func clearGlass() -> UIButton.Configuration {
116
+ #if compiler(>=6.2)
117
+ if #available(iOS 26.0, *) { return .clearGlass() }
118
+ #endif
119
+ return .gray()
120
+ }
121
+
122
+ /// `.prominentClearGlass()` needs the iOS 26 SDK and runtime; `.filled()` otherwise.
123
+ private static func prominentClearGlass() -> UIButton.Configuration {
124
+ #if compiler(>=6.2)
125
+ if #available(iOS 26.0, *) { return .prominentClearGlass() }
126
+ #endif
127
+ return .filled()
128
+ }
129
+
62
130
  /// Material's five sizes onto UIKit's four.
63
131
  static func buttonSize(_ size: String) -> UIButton.Configuration.Size {
64
132
  switch size {
@@ -87,15 +155,24 @@ enum PCButtonSupport {
87
155
  image: UIImage?,
88
156
  containerColor: UIColor?,
89
157
  foregroundColor: UIColor?,
90
- font: UIFont?
158
+ font: UIFont?,
159
+ imagePlacement: NSDirectionalRectEdge = .leading,
160
+ cornerRadius: CGFloat? = nil,
161
+ maxFontSizeMultiplier: CGFloat = 0,
162
+ traits: UITraitCollection? = nil
91
163
  ) -> UIButton.Configuration {
92
164
  var config = configuration(variant: variant, selected: selected)
93
165
  config.title = label.isEmpty ? nil : label
94
166
  config.image = image
95
167
  config.imagePadding = (image != nil && !label.isEmpty) ? 8 : 0
168
+ config.imagePlacement = imagePlacement
96
169
  config.buttonSize = buttonSize(size)
97
170
  config.titleLineBreakMode = .byTruncatingTail
98
- if let corner = cornerStyle(shape) {
171
+ if let cornerRadius {
172
+ // A numeric radius overrides the shape
173
+ config.cornerStyle = .fixed
174
+ config.background.cornerRadius = cornerRadius
175
+ } else if let corner = cornerStyle(shape) {
99
176
  config.cornerStyle = corner
100
177
  }
101
178
  if let containerColor {
@@ -104,26 +181,62 @@ enum PCButtonSupport {
104
181
  if let foregroundColor {
105
182
  config.baseForegroundColor = foregroundColor
106
183
  }
107
- if let font {
184
+ var titleFont = font
185
+ if titleFont == nil, maxFontSizeMultiplier >= 1, !label.isEmpty, let traits,
186
+ let systemFont = defaultTitleFont(for: config) {
187
+ titleFont = cappedFont(systemFont, maxFontSizeMultiplier: maxFontSizeMultiplier, traits: traits)
188
+ }
189
+ if let titleFont {
108
190
  config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
109
191
  var outgoing = incoming
110
- outgoing.font = font
192
+ outgoing.font = titleFont
111
193
  return outgoing
112
194
  }
113
195
  }
114
196
  return config
115
197
  }
116
198
 
199
+ /// The title font UIKit picks for a configuration, read from a throwaway
200
+ /// button.
201
+ private static func defaultTitleFont(for config: UIButton.Configuration) -> UIFont? {
202
+ let probe = UIButton(configuration: config)
203
+ probe.updateConfiguration()
204
+ probe.layoutIfNeeded()
205
+ return probe.titleLabel?.font
206
+ }
207
+
208
+ /// Caps a Dynamic Type font at `maxFontSizeMultiplier` times its size at
209
+ /// the default content size category, as React Native's `Text` does. The
210
+ /// size is read for `traits`, so the probe's own traits don't matter.
211
+ /// nil when the cap doesn't bind, or the font has no text style (it
212
+ /// doesn't scale), so UIKit keeps its own font.
213
+ static func cappedFont(_ font: UIFont, maxFontSizeMultiplier: CGFloat, traits: UITraitCollection) -> UIFont? {
214
+ guard maxFontSizeMultiplier >= 1,
215
+ let style = font.fontDescriptor.object(forKey: .textStyle) as? String
216
+ else { return nil }
217
+ let textStyle = UIFont.TextStyle(rawValue: style)
218
+ let defaultTraits = UITraitCollection(preferredContentSizeCategory: .large)
219
+ let base = UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: defaultTraits).pointSize
220
+ let current = UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: traits).pointSize
221
+ let cap = base * maxFontSizeMultiplier
222
+ guard current > cap else { return nil }
223
+ // A plain system font at the capped size: a font that keeps its text
224
+ // style could be scaled again by the label.
225
+ let fontTraits = font.fontDescriptor.object(forKey: .traits) as? [UIFontDescriptor.TraitKey: Any]
226
+ let weight = (fontTraits?[.weight] as? CGFloat).map { UIFont.Weight($0) } ?? .regular
227
+ return UIFont.systemFont(ofSize: cap, weight: weight)
228
+ }
229
+
117
230
  /// Resolves the icon's image. SF Symbols resolve synchronously; images
118
231
  /// that are still loading return nil and call `completion` on the main
119
232
  /// thread once they arrive.
120
233
  static func image(for icon: Icon, completion: @escaping (UIImage?) -> Void) -> UIImage? {
121
234
  switch icon.type {
122
235
  case "sfSymbol":
123
- return UIImage(systemName: icon.name).map { decorate($0, tinted: icon.tinted) }
236
+ return PCImageLoader.symbol(named: icon.name).map { decorate($0, tinted: icon.tinted) }
124
237
 
125
238
  case "image":
126
- let cached = PCImageLoader.shared.image(uri: icon.uri, scale: icon.scale) { image in
239
+ let cached = PCImageLoader.shared.image(uri: icon.uri, scale: icon.scale, request: icon.request) { image in
127
240
  completion(image.map { decorate($0, tinted: icon.tinted) })
128
241
  }
129
242
  return cached.map { decorate($0, tinted: icon.tinted) }
@@ -139,3 +252,61 @@ enum PCButtonSupport {
139
252
  image.withRenderingMode(tinted ? .alwaysTemplate : .alwaysOriginal)
140
253
  }
141
254
  }
255
+
256
+ /// SF Symbol effects for Button's `ios.symbolEffect`, through
257
+ /// `UIImageView.addSymbolEffect`. `bounce`, `pulse` and `variableColor` need
258
+ /// iOS 17; `wiggle`, `rotate` and `breathe` iOS 18. Unknown names and effects
259
+ /// the running iOS doesn't have do nothing.
260
+ @available(iOS 17.0, *)
261
+ enum PCSymbolEffects {
262
+ /// Adds the effect: repeating until the image view's effects are
263
+ /// removed, or played once.
264
+ static func add(_ name: String, to view: UIImageView, repeating: Bool) {
265
+ switch name {
266
+ case "bounce":
267
+ if repeating {
268
+ if #available(iOS 18.0, *) {
269
+ indefinite(.bounce, view)
270
+ } else {
271
+ // Bounce is a one-shot effect on iOS 17; repeat it
272
+ discrete(.bounce, view, options: .repeating)
273
+ }
274
+ } else {
275
+ discrete(.bounce, view)
276
+ }
277
+ case "pulse":
278
+ repeating ? indefinite(.pulse, view) : discrete(.pulse, view)
279
+ case "variableColor":
280
+ repeating ? indefinite(.variableColor, view) : discrete(.variableColor, view)
281
+ case "wiggle":
282
+ if #available(iOS 18.0, *) {
283
+ repeating ? indefinite(.wiggle, view) : discrete(.wiggle, view)
284
+ }
285
+ case "rotate":
286
+ if #available(iOS 18.0, *) {
287
+ repeating ? indefinite(.rotate, view) : discrete(.rotate, view)
288
+ }
289
+ case "breathe":
290
+ if #available(iOS 18.0, *) {
291
+ repeating ? indefinite(.breathe, view) : discrete(.breathe, view)
292
+ }
293
+ default:
294
+ break
295
+ }
296
+ }
297
+
298
+ // Typed entry points, so an effect that is both discrete and indefinite
299
+ // takes the overload that matches the mode.
300
+
301
+ private static func discrete(
302
+ _ effect: some DiscreteSymbolEffect & SymbolEffect,
303
+ _ view: UIImageView,
304
+ options: SymbolEffectOptions = .default
305
+ ) {
306
+ view.addSymbolEffect(effect, options: options)
307
+ }
308
+
309
+ private static func indefinite(_ effect: some IndefiniteSymbolEffect & SymbolEffect, _ view: UIImageView) {
310
+ view.addSymbolEffect(effect)
311
+ }
312
+ }