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.
- package/PlatformComponents.podspec +1 -1
- package/README.md +33 -31
- package/android/src/main/java/com/platformcomponents/PCButtonGroupView.kt +175 -9
- package/android/src/main/java/com/platformcomponents/PCButtonGroupViewManager.kt +52 -2
- package/android/src/main/java/com/platformcomponents/PCButtonSupport.kt +44 -12
- package/android/src/main/java/com/platformcomponents/PCButtonView.kt +187 -5
- package/android/src/main/java/com/platformcomponents/PCButtonViewManager.kt +85 -7
- package/android/src/main/java/com/platformcomponents/PCContextMenuView.kt +41 -151
- package/android/src/main/java/com/platformcomponents/PCContextMenuViewManager.kt +7 -63
- package/android/src/main/java/com/platformcomponents/PCDatePickerView.kt +310 -115
- package/android/src/main/java/com/platformcomponents/PCDatePickerViewManager.kt +23 -3
- package/android/src/main/java/com/platformcomponents/PCExpressive.kt +6 -1
- package/android/src/main/java/com/platformcomponents/PCFloatingActionButtonView.kt +485 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingActionButtonViewManager.kt +109 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarView.kt +132 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarViewManager.kt +8 -0
- package/android/src/main/java/com/platformcomponents/PCHaptics.kt +46 -0
- package/android/src/main/java/com/platformcomponents/PCImageLoader.kt +42 -7
- package/android/src/main/java/com/platformcomponents/PCLiquidGlassContainerView.kt +32 -0
- package/android/src/main/java/com/platformcomponents/PCLiquidGlassContainerViewManager.kt +31 -0
- package/android/src/main/java/com/platformcomponents/PCLiquidGlassView.kt +32 -6
- package/android/src/main/java/com/platformcomponents/PCLiquidGlassViewManager.kt +4 -0
- package/android/src/main/java/com/platformcomponents/PCMenuSupport.kt +280 -0
- package/android/src/main/java/com/platformcomponents/PCNavigationBarSupport.kt +332 -0
- package/android/src/main/java/com/platformcomponents/PCNavigationRailView.kt +448 -0
- package/android/src/main/java/com/platformcomponents/PCNavigationRailViewManager.kt +176 -0
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlView.kt +24 -14
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +14 -2
- package/android/src/main/java/com/platformcomponents/PCSelectionMenuView.kt +371 -39
- package/android/src/main/java/com/platformcomponents/PCSelectionMenuViewManager.kt +18 -4
- package/android/src/main/java/com/platformcomponents/PCTabBarView.kt +397 -0
- package/android/src/main/java/com/platformcomponents/PCTabBarViewManager.kt +182 -0
- package/android/src/main/java/com/platformcomponents/PCTextFieldView.kt +415 -40
- package/android/src/main/java/com/platformcomponents/PCTextFieldViewManager.kt +109 -3
- package/android/src/main/java/com/platformcomponents/PCThemeSupport.kt +37 -0
- package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +4 -0
- package/android/src/main/res/drawable/pc_ic_search.xml +12 -0
- package/android/src/main/res/values/ids.xml +5 -0
- package/android/src/main/res/values/styles.xml +24 -0
- package/ios/PCButton.mm +122 -7
- package/ios/PCButtonGroup.mm +68 -1
- package/ios/PCButtonGroupView.swift +225 -6
- package/ios/PCButtonSupport.swift +181 -10
- package/ios/PCButtonView.swift +297 -14
- package/ios/PCConstants.swift +23 -2
- package/ios/PCContextMenu.mm +28 -110
- package/ios/PCContextMenu.swift +106 -167
- package/ios/PCDatePicker.mm +21 -9
- package/ios/PCDatePickerView.swift +94 -20
- package/ios/PCFloatingActionButton.h +10 -0
- package/ios/PCFloatingActionButton.mm +177 -0
- package/ios/PCFloatingActionButtonView.swift +426 -0
- package/ios/PCFloatingToolbar.mm +27 -0
- package/ios/PCFloatingToolbarView.swift +241 -0
- package/ios/PCHaptics.swift +91 -0
- package/ios/PCImageLoader.swift +76 -12
- package/ios/PCLiquidGlass.mm +36 -0
- package/ios/PCLiquidGlass.swift +221 -114
- package/ios/PCLiquidGlassContainer.h +10 -0
- package/ios/PCLiquidGlassContainer.mm +84 -0
- package/ios/PCLiquidGlassContainer.swift +69 -0
- package/ios/PCMenuItems.h +76 -0
- package/ios/PCMenuSupport.swift +350 -0
- package/ios/PCNavigationRail.h +10 -0
- package/ios/PCNavigationRail.mm +270 -0
- package/ios/PCNavigationRailView.swift +415 -0
- package/ios/PCSegmentedControl.mm +17 -2
- package/ios/PCSegmentedControl.swift +57 -7
- package/ios/PCSelectionMenu.mm +36 -8
- package/ios/PCSelectionMenu.swift +224 -48
- package/ios/PCTabBar.h +10 -0
- package/ios/PCTabBar.mm +285 -0
- package/ios/PCTabBarAccessory.h +10 -0
- package/ios/PCTabBarAccessory.mm +93 -0
- package/ios/PCTabBarAccessoryView.swift +96 -0
- package/ios/PCTabBarView.swift +671 -0
- package/ios/PCTextField.mm +159 -4
- package/ios/PCTextFieldView.swift +603 -57
- package/lib/commonjs/Button.js +73 -1
- package/lib/commonjs/Button.js.map +1 -1
- package/lib/commonjs/ButtonGroup.js +13 -3
- package/lib/commonjs/ButtonGroup.js.map +1 -1
- package/lib/commonjs/ButtonGroupNativeComponent.ts +74 -4
- package/lib/commonjs/ButtonNativeComponent.ts +119 -3
- package/lib/commonjs/ContextMenu.js +9 -48
- package/lib/commonjs/ContextMenu.js.map +1 -1
- package/lib/commonjs/ContextMenuNativeComponent.ts +47 -49
- package/lib/commonjs/DatePicker.js +98 -2
- package/lib/commonjs/DatePicker.js.map +1 -1
- package/lib/commonjs/DatePickerNativeComponent.ts +19 -2
- package/lib/commonjs/FloatingActionButton.js +60 -0
- package/lib/commonjs/FloatingActionButton.js.map +1 -0
- package/lib/commonjs/FloatingActionButtonNativeComponent.ts +58 -0
- package/lib/commonjs/FloatingToolbar.js +9 -1
- package/lib/commonjs/FloatingToolbar.js.map +1 -1
- package/lib/commonjs/FloatingToolbarNativeComponent.ts +16 -0
- package/lib/commonjs/LiquidGlass.js +7 -1
- package/lib/commonjs/LiquidGlass.js.map +1 -1
- package/lib/commonjs/LiquidGlassContainer.js +32 -0
- package/lib/commonjs/LiquidGlassContainer.js.map +1 -0
- package/lib/commonjs/LiquidGlassContainerNativeComponent.ts +17 -0
- package/lib/commonjs/LiquidGlassNativeComponent.ts +8 -0
- package/lib/commonjs/NavigationRail.js +104 -0
- package/lib/commonjs/NavigationRail.js.map +1 -0
- package/lib/commonjs/NavigationRailNativeComponent.ts +107 -0
- package/lib/commonjs/PlatformComponentsProvider.js +18 -0
- package/lib/commonjs/PlatformComponentsProvider.js.map +1 -0
- package/lib/commonjs/SegmentedControl.js +7 -0
- package/lib/commonjs/SegmentedControl.js.map +1 -1
- package/lib/commonjs/SegmentedControlNativeComponent.ts +11 -0
- package/lib/commonjs/SelectionMenu.js +27 -3
- package/lib/commonjs/SelectionMenu.js.map +1 -1
- package/lib/commonjs/SelectionMenuNativeComponent.ts +26 -4
- package/lib/commonjs/SplitButton.js +98 -0
- package/lib/commonjs/SplitButton.js.map +1 -0
- package/lib/commonjs/TabBar.js +203 -0
- package/lib/commonjs/TabBar.js.map +1 -0
- package/lib/commonjs/TabBarAccessoryNativeComponent.ts +19 -0
- package/lib/commonjs/TabBarNativeComponent.ts +145 -0
- package/lib/commonjs/TextField.js +171 -8
- package/lib/commonjs/TextField.js.map +1 -1
- package/lib/commonjs/TextFieldNativeComponent.ts +110 -4
- package/lib/commonjs/focusRegistry.js +2 -1
- package/lib/commonjs/focusRegistry.js.map +1 -1
- package/lib/commonjs/haptics.js +2 -0
- package/lib/commonjs/haptics.js.map +1 -0
- package/lib/commonjs/icons.js +15 -1
- package/lib/commonjs/icons.js.map +1 -1
- package/lib/commonjs/index.js +77 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +156 -92
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/jest.js +910 -0
- package/lib/commonjs/jest.js.map +1 -0
- package/lib/commonjs/menuItems.js +68 -0
- package/lib/commonjs/menuItems.js.map +1 -0
- package/lib/commonjs/selectionIdentifiers.js +18 -0
- package/lib/commonjs/selectionIdentifiers.js.map +1 -0
- package/lib/commonjs/submitBehavior.js +19 -0
- package/lib/commonjs/submitBehavior.js.map +1 -0
- package/lib/commonjs/tabItems.js +49 -0
- package/lib/commonjs/tabItems.js.map +1 -0
- package/lib/commonjs/web/Button.js +170 -0
- package/lib/commonjs/web/Button.js.map +1 -0
- package/lib/commonjs/web/ButtonGroup.js +119 -0
- package/lib/commonjs/web/ButtonGroup.js.map +1 -0
- package/lib/commonjs/web/DatePicker.js +168 -0
- package/lib/commonjs/web/DatePicker.js.map +1 -0
- package/lib/commonjs/web/DateRangePicker.js +137 -0
- package/lib/commonjs/web/DateRangePicker.js.map +1 -0
- package/lib/commonjs/web/Dialog.js +54 -0
- package/lib/commonjs/web/Dialog.js.map +1 -0
- package/lib/commonjs/web/FloatingActionButton.js +98 -0
- package/lib/commonjs/web/FloatingActionButton.js.map +1 -0
- package/lib/commonjs/web/Icon.js +34 -0
- package/lib/commonjs/web/Icon.js.map +1 -0
- package/lib/commonjs/web/NativeTheme.js +28 -0
- package/lib/commonjs/web/NativeTheme.js.map +1 -0
- package/lib/commonjs/web/NavigationRail.js +139 -0
- package/lib/commonjs/web/NavigationRail.js.map +1 -0
- package/lib/commonjs/web/PlatformComponentsProvider.js +51 -0
- package/lib/commonjs/web/PlatformComponentsProvider.js.map +1 -0
- package/lib/commonjs/web/SegmentedControl.js +117 -0
- package/lib/commonjs/web/SegmentedControl.js.map +1 -0
- package/lib/commonjs/web/SelectionMenu.js +142 -0
- package/lib/commonjs/web/SelectionMenu.js.map +1 -0
- package/lib/commonjs/web/SplitButton.js +35 -0
- package/lib/commonjs/web/SplitButton.js.map +1 -0
- package/lib/commonjs/web/TabBar.js +131 -0
- package/lib/commonjs/web/TabBar.js.map +1 -0
- package/lib/commonjs/web/TextField.js +322 -0
- package/lib/commonjs/web/TextField.js.map +1 -0
- package/lib/commonjs/web/components.js +36 -0
- package/lib/commonjs/web/components.js.map +1 -0
- package/lib/commonjs/web/containers.js +121 -0
- package/lib/commonjs/web/containers.js.map +1 -0
- package/lib/commonjs/web/dateInput.js +116 -0
- package/lib/commonjs/web/dateInput.js.map +1 -0
- package/lib/commonjs/web/shared.js +192 -0
- package/lib/commonjs/web/shared.js.map +1 -0
- package/lib/commonjs/webComponents.js +6 -0
- package/lib/commonjs/webComponents.js.map +1 -0
- package/lib/module/Button.js +74 -2
- package/lib/module/Button.js.map +1 -1
- package/lib/module/ButtonGroup.js +13 -3
- package/lib/module/ButtonGroup.js.map +1 -1
- package/lib/module/ButtonGroupNativeComponent.ts +74 -4
- package/lib/module/ButtonNativeComponent.ts +119 -3
- package/lib/module/ContextMenu.js +9 -48
- package/lib/module/ContextMenu.js.map +1 -1
- package/lib/module/ContextMenuNativeComponent.ts +47 -49
- package/lib/module/DatePicker.js +98 -4
- package/lib/module/DatePicker.js.map +1 -1
- package/lib/module/DatePickerNativeComponent.ts +19 -2
- package/lib/module/FloatingActionButton.js +53 -0
- package/lib/module/FloatingActionButton.js.map +1 -0
- package/lib/module/FloatingActionButtonNativeComponent.ts +58 -0
- package/lib/module/FloatingToolbar.js +9 -1
- package/lib/module/FloatingToolbar.js.map +1 -1
- package/lib/module/FloatingToolbarNativeComponent.ts +16 -0
- package/lib/module/LiquidGlass.js +7 -1
- package/lib/module/LiquidGlass.js.map +1 -1
- package/lib/module/LiquidGlassContainer.js +26 -0
- package/lib/module/LiquidGlassContainer.js.map +1 -0
- package/lib/module/LiquidGlassContainerNativeComponent.ts +17 -0
- package/lib/module/LiquidGlassNativeComponent.ts +8 -0
- package/lib/module/NavigationRail.js +99 -0
- package/lib/module/NavigationRail.js.map +1 -0
- package/lib/module/NavigationRailNativeComponent.ts +107 -0
- package/lib/module/PlatformComponentsProvider.js +13 -0
- package/lib/module/PlatformComponentsProvider.js.map +1 -0
- package/lib/module/SegmentedControl.js +9 -1
- package/lib/module/SegmentedControl.js.map +1 -1
- package/lib/module/SegmentedControlNativeComponent.ts +11 -0
- package/lib/module/SelectionMenu.js +27 -3
- package/lib/module/SelectionMenu.js.map +1 -1
- package/lib/module/SelectionMenuNativeComponent.ts +26 -4
- package/lib/module/SplitButton.js +91 -0
- package/lib/module/SplitButton.js.map +1 -0
- package/lib/module/TabBar.js +196 -0
- package/lib/module/TabBar.js.map +1 -0
- package/lib/module/TabBarAccessoryNativeComponent.ts +19 -0
- package/lib/module/TabBarNativeComponent.ts +145 -0
- package/lib/module/TextField.js +172 -9
- package/lib/module/TextField.js.map +1 -1
- package/lib/module/TextFieldNativeComponent.ts +110 -4
- package/lib/module/focusRegistry.js +1 -0
- package/lib/module/focusRegistry.js.map +1 -1
- package/lib/module/haptics.js +2 -0
- package/lib/module/haptics.js.map +1 -0
- package/lib/module/icons.js +15 -1
- package/lib/module/icons.js.map +1 -1
- package/lib/module/index.js +7 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +12 -87
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/jest.js +840 -0
- package/lib/module/jest.js.map +1 -0
- package/lib/module/menuItems.js +65 -0
- package/lib/module/menuItems.js.map +1 -0
- package/lib/module/selectionIdentifiers.js +14 -0
- package/lib/module/selectionIdentifiers.js.map +1 -0
- package/lib/module/submitBehavior.js +15 -0
- package/lib/module/submitBehavior.js.map +1 -0
- package/lib/module/tabItems.js +45 -0
- package/lib/module/tabItems.js.map +1 -0
- package/lib/module/web/Button.js +164 -0
- package/lib/module/web/Button.js.map +1 -0
- package/lib/module/web/ButtonGroup.js +113 -0
- package/lib/module/web/ButtonGroup.js.map +1 -0
- package/lib/module/web/DatePicker.js +162 -0
- package/lib/module/web/DatePicker.js.map +1 -0
- package/lib/module/web/DateRangePicker.js +131 -0
- package/lib/module/web/DateRangePicker.js.map +1 -0
- package/lib/module/web/Dialog.js +48 -0
- package/lib/module/web/Dialog.js.map +1 -0
- package/lib/module/web/FloatingActionButton.js +94 -0
- package/lib/module/web/FloatingActionButton.js.map +1 -0
- package/lib/module/web/Icon.js +29 -0
- package/lib/module/web/Icon.js.map +1 -0
- package/lib/module/web/NativeTheme.js +23 -0
- package/lib/module/web/NativeTheme.js.map +1 -0
- package/lib/module/web/NavigationRail.js +133 -0
- package/lib/module/web/NavigationRail.js.map +1 -0
- package/lib/module/web/PlatformComponentsProvider.js +44 -0
- package/lib/module/web/PlatformComponentsProvider.js.map +1 -0
- package/lib/module/web/SegmentedControl.js +112 -0
- package/lib/module/web/SegmentedControl.js.map +1 -0
- package/lib/module/web/SelectionMenu.js +137 -0
- package/lib/module/web/SelectionMenu.js.map +1 -0
- package/lib/module/web/SplitButton.js +30 -0
- package/lib/module/web/SplitButton.js.map +1 -0
- package/lib/module/web/TabBar.js +126 -0
- package/lib/module/web/TabBar.js.map +1 -0
- package/lib/module/web/TextField.js +316 -0
- package/lib/module/web/TextField.js.map +1 -0
- package/lib/module/web/components.js +33 -0
- package/lib/module/web/components.js.map +1 -0
- package/lib/module/web/containers.js +112 -0
- package/lib/module/web/containers.js.map +1 -0
- package/lib/module/web/dateInput.js +109 -0
- package/lib/module/web/dateInput.js.map +1 -0
- package/lib/module/web/shared.js +179 -0
- package/lib/module/web/shared.js.map +1 -0
- package/lib/module/webComponents.js +4 -0
- package/lib/module/webComponents.js.map +1 -0
- package/lib/typescript/commonjs/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/Button.d.ts +111 -3
- package/lib/typescript/commonjs/src/Button.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts +21 -6
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts +64 -3
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts +94 -3
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/ContextMenu.d.ts +20 -33
- package/lib/typescript/commonjs/src/ContextMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts +45 -47
- package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/DatePicker.d.ts +74 -1
- package/lib/typescript/commonjs/src/DatePicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts +16 -1
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/FloatingActionButton.d.ts +67 -0
- package/lib/typescript/commonjs/src/FloatingActionButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/FloatingActionButtonNativeComponent.d.ts +43 -0
- package/lib/typescript/commonjs/src/FloatingActionButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts +30 -0
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts +12 -0
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/LiquidGlass.d.ts +17 -0
- package/lib/typescript/commonjs/src/LiquidGlass.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/LiquidGlassContainer.d.ts +27 -0
- package/lib/typescript/commonjs/src/LiquidGlassContainer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/LiquidGlassContainerNativeComponent.d.ts +13 -0
- package/lib/typescript/commonjs/src/LiquidGlassContainerNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts +7 -0
- package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/NavigationRail.d.ts +86 -0
- package/lib/typescript/commonjs/src/NavigationRail.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/NavigationRailNativeComponent.d.ts +81 -0
- package/lib/typescript/commonjs/src/NavigationRailNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/PlatformComponentsProvider.d.ts +6 -0
- package/lib/typescript/commonjs/src/PlatformComponentsProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts +18 -1
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +9 -0
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SelectionMenu.d.ts +44 -2
- package/lib/typescript/commonjs/src/SelectionMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts +20 -4
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SplitButton.d.ts +83 -0
- package/lib/typescript/commonjs/src/SplitButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TabBar.d.ts +144 -0
- package/lib/typescript/commonjs/src/TabBar.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TabBarAccessoryNativeComponent.d.ts +13 -0
- package/lib/typescript/commonjs/src/TabBarAccessoryNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TabBarNativeComponent.d.ts +110 -0
- package/lib/typescript/commonjs/src/TabBarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TextField.d.ts +166 -8
- package/lib/typescript/commonjs/src/TextField.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts +81 -3
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/focusRegistry.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/haptics.d.ts +20 -0
- package/lib/typescript/commonjs/src/haptics.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/icons.d.ts +7 -1
- package/lib/typescript/commonjs/src/icons.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +7 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.web.d.ts +25 -254
- package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/jest.d.ts +139 -0
- package/lib/typescript/commonjs/src/jest.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/menuItems.d.ts +100 -0
- package/lib/typescript/commonjs/src/menuItems.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts +3 -0
- package/lib/typescript/commonjs/src/selectionIdentifiers.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/submitBehavior.d.ts +9 -0
- package/lib/typescript/commonjs/src/submitBehavior.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/tabItems.d.ts +55 -0
- package/lib/typescript/commonjs/src/tabItems.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/Button.d.ts +9 -0
- package/lib/typescript/commonjs/src/web/Button.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/ButtonGroup.d.ts +11 -0
- package/lib/typescript/commonjs/src/web/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/DatePicker.d.ts +14 -0
- package/lib/typescript/commonjs/src/web/DatePicker.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/DateRangePicker.d.ts +11 -0
- package/lib/typescript/commonjs/src/web/DateRangePicker.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/Dialog.d.ts +12 -0
- package/lib/typescript/commonjs/src/web/Dialog.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/FloatingActionButton.d.ts +8 -0
- package/lib/typescript/commonjs/src/web/FloatingActionButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/Icon.d.ts +12 -0
- package/lib/typescript/commonjs/src/web/Icon.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/NativeTheme.d.ts +10 -0
- package/lib/typescript/commonjs/src/web/NativeTheme.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/NavigationRail.d.ts +8 -0
- package/lib/typescript/commonjs/src/web/NavigationRail.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/PlatformComponentsProvider.d.ts +10 -0
- package/lib/typescript/commonjs/src/web/PlatformComponentsProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/SegmentedControl.d.ts +8 -0
- package/lib/typescript/commonjs/src/web/SegmentedControl.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/SelectionMenu.d.ts +10 -0
- package/lib/typescript/commonjs/src/web/SelectionMenu.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/SplitButton.d.ts +9 -0
- package/lib/typescript/commonjs/src/web/SplitButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/TabBar.d.ts +9 -0
- package/lib/typescript/commonjs/src/web/TabBar.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/TextField.d.ts +9 -0
- package/lib/typescript/commonjs/src/web/TextField.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/components.d.ts +17 -0
- package/lib/typescript/commonjs/src/web/components.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/containers.d.ts +24 -0
- package/lib/typescript/commonjs/src/web/containers.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/dateInput.d.ts +20 -0
- package/lib/typescript/commonjs/src/web/dateInput.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/shared.d.ts +43 -0
- package/lib/typescript/commonjs/src/web/shared.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/webComponents.d.ts +43 -0
- package/lib/typescript/commonjs/src/webComponents.d.ts.map +1 -0
- package/lib/typescript/module/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/module/src/Button.d.ts +111 -3
- package/lib/typescript/module/src/Button.d.ts.map +1 -1
- package/lib/typescript/module/src/ButtonGroup.d.ts +21 -6
- package/lib/typescript/module/src/ButtonGroup.d.ts.map +1 -1
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts +64 -3
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts +94 -3
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/ContextMenu.d.ts +20 -33
- package/lib/typescript/module/src/ContextMenu.d.ts.map +1 -1
- package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts +45 -47
- package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePicker.d.ts +74 -1
- package/lib/typescript/module/src/DatePicker.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts +16 -1
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/FloatingActionButton.d.ts +67 -0
- package/lib/typescript/module/src/FloatingActionButton.d.ts.map +1 -0
- package/lib/typescript/module/src/FloatingActionButtonNativeComponent.d.ts +43 -0
- package/lib/typescript/module/src/FloatingActionButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/FloatingToolbar.d.ts +30 -0
- package/lib/typescript/module/src/FloatingToolbar.d.ts.map +1 -1
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts +12 -0
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/LiquidGlass.d.ts +17 -0
- package/lib/typescript/module/src/LiquidGlass.d.ts.map +1 -1
- package/lib/typescript/module/src/LiquidGlassContainer.d.ts +27 -0
- package/lib/typescript/module/src/LiquidGlassContainer.d.ts.map +1 -0
- package/lib/typescript/module/src/LiquidGlassContainerNativeComponent.d.ts +13 -0
- package/lib/typescript/module/src/LiquidGlassContainerNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts +7 -0
- package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/NavigationRail.d.ts +86 -0
- package/lib/typescript/module/src/NavigationRail.d.ts.map +1 -0
- package/lib/typescript/module/src/NavigationRailNativeComponent.d.ts +81 -0
- package/lib/typescript/module/src/NavigationRailNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/PlatformComponentsProvider.d.ts +6 -0
- package/lib/typescript/module/src/PlatformComponentsProvider.d.ts.map +1 -0
- package/lib/typescript/module/src/SegmentedControl.d.ts +18 -1
- package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +9 -0
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/SelectionMenu.d.ts +44 -2
- package/lib/typescript/module/src/SelectionMenu.d.ts.map +1 -1
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts +20 -4
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/SplitButton.d.ts +83 -0
- package/lib/typescript/module/src/SplitButton.d.ts.map +1 -0
- package/lib/typescript/module/src/TabBar.d.ts +144 -0
- package/lib/typescript/module/src/TabBar.d.ts.map +1 -0
- package/lib/typescript/module/src/TabBarAccessoryNativeComponent.d.ts +13 -0
- package/lib/typescript/module/src/TabBarAccessoryNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/TabBarNativeComponent.d.ts +110 -0
- package/lib/typescript/module/src/TabBarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/TextField.d.ts +166 -8
- package/lib/typescript/module/src/TextField.d.ts.map +1 -1
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts +81 -3
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/focusRegistry.d.ts.map +1 -1
- package/lib/typescript/module/src/haptics.d.ts +20 -0
- package/lib/typescript/module/src/haptics.d.ts.map +1 -0
- package/lib/typescript/module/src/icons.d.ts +7 -1
- package/lib/typescript/module/src/icons.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +7 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/index.web.d.ts +25 -254
- package/lib/typescript/module/src/index.web.d.ts.map +1 -1
- package/lib/typescript/module/src/jest.d.ts +139 -0
- package/lib/typescript/module/src/jest.d.ts.map +1 -0
- package/lib/typescript/module/src/menuItems.d.ts +100 -0
- package/lib/typescript/module/src/menuItems.d.ts.map +1 -0
- package/lib/typescript/module/src/selectionIdentifiers.d.ts +3 -0
- package/lib/typescript/module/src/selectionIdentifiers.d.ts.map +1 -0
- package/lib/typescript/module/src/submitBehavior.d.ts +9 -0
- package/lib/typescript/module/src/submitBehavior.d.ts.map +1 -0
- package/lib/typescript/module/src/tabItems.d.ts +55 -0
- package/lib/typescript/module/src/tabItems.d.ts.map +1 -0
- package/lib/typescript/module/src/web/Button.d.ts +9 -0
- package/lib/typescript/module/src/web/Button.d.ts.map +1 -0
- package/lib/typescript/module/src/web/ButtonGroup.d.ts +11 -0
- package/lib/typescript/module/src/web/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/module/src/web/DatePicker.d.ts +14 -0
- package/lib/typescript/module/src/web/DatePicker.d.ts.map +1 -0
- package/lib/typescript/module/src/web/DateRangePicker.d.ts +11 -0
- package/lib/typescript/module/src/web/DateRangePicker.d.ts.map +1 -0
- package/lib/typescript/module/src/web/Dialog.d.ts +12 -0
- package/lib/typescript/module/src/web/Dialog.d.ts.map +1 -0
- package/lib/typescript/module/src/web/FloatingActionButton.d.ts +8 -0
- package/lib/typescript/module/src/web/FloatingActionButton.d.ts.map +1 -0
- package/lib/typescript/module/src/web/Icon.d.ts +12 -0
- package/lib/typescript/module/src/web/Icon.d.ts.map +1 -0
- package/lib/typescript/module/src/web/NativeTheme.d.ts +10 -0
- package/lib/typescript/module/src/web/NativeTheme.d.ts.map +1 -0
- package/lib/typescript/module/src/web/NavigationRail.d.ts +8 -0
- package/lib/typescript/module/src/web/NavigationRail.d.ts.map +1 -0
- package/lib/typescript/module/src/web/PlatformComponentsProvider.d.ts +10 -0
- package/lib/typescript/module/src/web/PlatformComponentsProvider.d.ts.map +1 -0
- package/lib/typescript/module/src/web/SegmentedControl.d.ts +8 -0
- package/lib/typescript/module/src/web/SegmentedControl.d.ts.map +1 -0
- package/lib/typescript/module/src/web/SelectionMenu.d.ts +10 -0
- package/lib/typescript/module/src/web/SelectionMenu.d.ts.map +1 -0
- package/lib/typescript/module/src/web/SplitButton.d.ts +9 -0
- package/lib/typescript/module/src/web/SplitButton.d.ts.map +1 -0
- package/lib/typescript/module/src/web/TabBar.d.ts +9 -0
- package/lib/typescript/module/src/web/TabBar.d.ts.map +1 -0
- package/lib/typescript/module/src/web/TextField.d.ts +9 -0
- package/lib/typescript/module/src/web/TextField.d.ts.map +1 -0
- package/lib/typescript/module/src/web/components.d.ts +17 -0
- package/lib/typescript/module/src/web/components.d.ts.map +1 -0
- package/lib/typescript/module/src/web/containers.d.ts +24 -0
- package/lib/typescript/module/src/web/containers.d.ts.map +1 -0
- package/lib/typescript/module/src/web/dateInput.d.ts +20 -0
- package/lib/typescript/module/src/web/dateInput.d.ts.map +1 -0
- package/lib/typescript/module/src/web/shared.d.ts +43 -0
- package/lib/typescript/module/src/web/shared.d.ts.map +1 -0
- package/lib/typescript/module/src/webComponents.d.ts +43 -0
- package/lib/typescript/module/src/webComponents.d.ts.map +1 -0
- package/package.json +32 -2
- package/plugin/build/index.cjs +79 -6
- package/plugin/build/index.d.ts +27 -2
- package/plugin/build/index.d.ts.map +1 -1
- package/plugin/tsconfig.json +2 -1
- package/react-native.config.js +3 -0
- package/shared/PCFloatingActionButtonComponentDescriptors-custom.h +22 -0
- package/shared/PCFloatingActionButtonShadowNode-custom.cpp +48 -0
- package/shared/PCFloatingActionButtonShadowNode-custom.h +54 -0
- package/shared/PCFloatingActionButtonState-custom.h +61 -0
- package/shared/PCNavigationRailComponentDescriptors-custom.h +47 -0
- package/shared/PCNavigationRailShadowNode-custom.h +42 -0
- package/shared/PCNavigationRailState-custom.h +62 -0
- package/shared/PCTabBarComponentDescriptors-custom.h +22 -0
- package/shared/PCTabBarShadowNode-custom.cpp +54 -0
- package/shared/PCTabBarShadowNode-custom.h +54 -0
- package/shared/PCTabBarState-custom.h +62 -0
- package/shared/react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h +3 -0
- package/src/Button.tsx +222 -7
- package/src/ButtonGroup.tsx +29 -11
- package/src/ButtonGroupNativeComponent.ts +74 -4
- package/src/ButtonNativeComponent.ts +119 -3
- package/src/ContextMenu.tsx +34 -81
- package/src/ContextMenuNativeComponent.ts +47 -49
- package/src/DatePicker.tsx +182 -4
- package/src/DatePickerNativeComponent.ts +19 -2
- package/src/FloatingActionButton.tsx +121 -0
- package/src/FloatingActionButtonNativeComponent.ts +58 -0
- package/src/FloatingToolbar.tsx +54 -3
- package/src/FloatingToolbarNativeComponent.ts +16 -0
- package/src/LiquidGlass.tsx +24 -1
- package/src/LiquidGlassContainer.tsx +42 -0
- package/src/LiquidGlassContainerNativeComponent.ts +17 -0
- package/src/LiquidGlassNativeComponent.ts +8 -0
- package/src/NavigationRail.tsx +203 -0
- package/src/NavigationRailNativeComponent.ts +107 -0
- package/src/PlatformComponentsProvider.tsx +15 -0
- package/src/SegmentedControl.tsx +31 -1
- package/src/SegmentedControlNativeComponent.ts +11 -0
- package/src/SelectionMenu.tsx +81 -6
- package/src/SelectionMenuNativeComponent.ts +26 -4
- package/src/SplitButton.tsx +198 -0
- package/src/TabBar.tsx +373 -0
- package/src/TabBarAccessoryNativeComponent.ts +19 -0
- package/src/TabBarNativeComponent.ts +145 -0
- package/src/TextField.tsx +428 -14
- package/src/TextFieldNativeComponent.ts +110 -4
- package/src/focusRegistry.ts +1 -0
- package/src/haptics.ts +31 -0
- package/src/icons.ts +28 -1
- package/src/index.tsx +7 -0
- package/src/index.web.tsx +51 -391
- package/src/jest.tsx +958 -0
- package/src/menuItems.ts +152 -0
- package/src/selectionIdentifiers.ts +17 -0
- package/src/submitBehavior.ts +16 -0
- package/src/tabItems.ts +113 -0
- package/src/web/Button.tsx +201 -0
- package/src/web/ButtonGroup.tsx +154 -0
- package/src/web/DatePicker.tsx +204 -0
- package/src/web/DateRangePicker.tsx +135 -0
- package/src/web/Dialog.tsx +54 -0
- package/src/web/FloatingActionButton.tsx +76 -0
- package/src/web/Icon.tsx +33 -0
- package/src/web/NativeTheme.ts +23 -0
- package/src/web/NavigationRail.tsx +148 -0
- package/src/web/PlatformComponentsProvider.tsx +48 -0
- package/src/web/SegmentedControl.tsx +127 -0
- package/src/web/SelectionMenu.tsx +149 -0
- package/src/web/SplitButton.tsx +32 -0
- package/src/web/TabBar.tsx +150 -0
- package/src/web/TextField.tsx +361 -0
- package/src/web/components.tsx +71 -0
- package/src/web/containers.tsx +130 -0
- package/src/web/dateInput.ts +137 -0
- package/src/web/shared.ts +176 -0
- package/src/webComponents.ts +45 -0
- package/android/src/main/java/com/platformcomponents/DateConstraints.kt +0 -83
|
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.authors = package["author"]
|
|
12
12
|
|
|
13
13
|
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
-
s.source = { :git => "https://github.com/JarX-Concepts/react-native-platform-components.git", :tag => "#{s.version}" }
|
|
14
|
+
s.source = { :git => "https://github.com/JarX-Concepts/react-native-platform-components.git", :tag => "v#{s.version}" }
|
|
15
15
|
|
|
16
16
|
s.source_files = ["ios/**/*.{h,m,mm,swift,cpp}", "shared/**/*.{h,m,mm,swift,cpp}"]
|
|
17
17
|
s.private_header_files = ["ios/**/*.h", "shared/**/*.h"]
|
package/README.md
CHANGED
|
@@ -5,20 +5,20 @@
|
|
|
5
5
|
[](https://github.com/JarX-Concepts/react-native-platform-components/actions/workflows/ci.yml)
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
|
|
8
|
-
Native **TextField**, **DatePicker**, **ContextMenu**, **SelectionMenu**, **SegmentedControl**, **Button**, **ButtonGroup**, **FloatingToolbar** and **LiquidGlass** for React Native. Every component is the real platform widget on both iOS and Android (UIKit
|
|
8
|
+
Native **TextField**, **DatePicker**, **ContextMenu**, **SelectionMenu**, **SegmentedControl**, **TabBar**, **NavigationRail**, **Button**, **ButtonGroup**, **FloatingActionButton**, **FloatingToolbar** and **LiquidGlass** for React Native. Every component is the real platform widget on both iOS and Android (UIKit on iOS, Material 3 Expressive on Android), behind one typed, declarative API. No JavaScript re-implementations.
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
11
|
<a href="https://jarx-concepts.github.io/react-native-platform-components">
|
|
12
12
|
<picture>
|
|
13
13
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/hero-dark.webp" />
|
|
14
|
-
<img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/hero-light.webp" alt="DatePicker, TextField, SegmentedControl, Button, ContextMenu, LiquidGlass, FloatingToolbar and SelectionMenu on iOS and Android, and the dark mode from useNativeTheme" />
|
|
14
|
+
<img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/hero-light.webp" alt="DatePicker, TextField, SegmentedControl, Button, TabBar, NavigationRail, FloatingActionButton, ContextMenu, LiquidGlass, FloatingToolbar and SelectionMenu on iOS and Android, and the dark mode from useNativeTheme" />
|
|
15
15
|
</picture>
|
|
16
16
|
</a>
|
|
17
17
|
</p>
|
|
18
18
|
<p align="center"><sub>Every tile is the platform's own widget, captured from the example app. The <a href="https://jarx-concepts.github.io/react-native-platform-components">docs site</a> has full recordings of each component on both platforms; <a href="https://jarx-concepts.github.io/react-native-platform-components/components/liquidglass">LiquidGlass</a> is iOS 26 only.</sub></p>
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
|
-
<a href="https://jarx-concepts.github.io/react-native-platform-components"><img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/showreel.gif" width="640" alt="Showreel: the native theme changing brand color and switching to dark mode, then DatePicker, TextField, SegmentedControl, Button, ContextMenu, SelectionMenu, FloatingToolbar and LiquidGlass in use, iOS on the left and Android on the right" /></a>
|
|
21
|
+
<a href="https://jarx-concepts.github.io/react-native-platform-components"><img src="https://raw.githubusercontent.com/JarX-Concepts/react-native-platform-components/main/assets/showreel.gif" width="640" alt="Showreel: the native theme changing brand color and switching to dark mode, then DatePicker, TextField, SegmentedControl, TabBar, NavigationRail, Button, FloatingActionButton, ContextMenu, SelectionMenu, FloatingToolbar and LiquidGlass in use, iOS on the left and Android on the right" /></a>
|
|
22
22
|
</p>
|
|
23
23
|
<p align="center"><sub>iOS on the left, Android on the right. Recorded by the Detox suite in <code>example/</code>.</sub></p>
|
|
24
24
|
|
|
@@ -41,32 +41,24 @@ import { SegmentedControl } from 'react-native-platform-components';
|
|
|
41
41
|
|
|
42
42
|
That renders `UISegmentedControl` on iOS and Material 3 segmented buttons (`MaterialButtonToggleGroup`) on Android. The library needs the New Architecture: React Native 0.81+, or Expo SDK 54+ with a dev client (not Expo Go). See [Installation](#installation) and the [documentation site](https://jarx-concepts.github.io/react-native-platform-components).
|
|
43
43
|
|
|
44
|
-
## Why this library
|
|
45
|
-
|
|
46
|
-
| You need | This library | Common alternative |
|
|
47
|
-
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
48
|
-
| Text field | Material 3 `TextInputLayout` on Android (floating label, outlined or filled, supporting text, error state, icons, counter); `UITextField` on iOS with Writing Tools, inline predictions and smart punctuation. Same `value` / `onChangeText` contract as `TextInput`. | `TextInput`: a bare `EditText` on Android, no Material field; the iOS 17 and 18 text traits are not exposed. `react-native-paper`: Material 3 drawn in JavaScript. |
|
|
49
|
-
| Date and time pickers | `UIDatePicker` on iOS; `MaterialDatePicker` / `MaterialTimePicker` or the AppCompat dialogs on Android. Declarative `visible` prop, modal or embedded. | `@react-native-community/datetimepicker`: platform dialogs on Android; Material 3 pickers are an [open request](https://github.com/react-native-datetimepicker/datetimepicker/issues/790). |
|
|
50
|
-
| Segmented control | `UISegmentedControl` on iOS; Material 3 segmented buttons on Android. Icons and badges on both. | `@react-native-segmented-control/segmented-control`: native on iOS, drawn in JavaScript on Android. |
|
|
51
|
-
| Context menu | `UIContextMenuInteraction` on iOS; `PopupMenu` on Android. Long-press gesture or modal trigger, icons on both. | `zeego`: native on both platforms, through two additional native dependencies (`react-native-ios-context-menu`, `@react-native-menu/menu`). |
|
|
52
|
-
| Selection menu | System menus on iOS; Material exposed dropdown or `Spinner` on Android. Headless or inline. | `@react-native-picker/picker`: wheel picker on iOS, dialog or dropdown `Spinner` on Android; no menu-style presentation. |
|
|
53
|
-
| Buttons and toolbars | Material 3 Expressive `MaterialButton`, button groups and `FloatingToolbarLayout` on Android (five sizes, shape morphing); `UIButton` configurations and a Liquid Glass toolbar on iOS. | `react-native-paper`: Material 3 (not Expressive) drawn in JavaScript on both platforms. |
|
|
54
|
-
| Liquid glass | `UIGlassEffect` on iOS 26+, a fallback `View` elsewhere, `isLiquidGlassSupported` flag. | `@callstack/liquid-glass`, `expo-glass-effect`: same idea on iOS; here it ships with the components above. |
|
|
55
|
-
| All of the above | One package, one API shape (platform-only props under `ios={{ }}` and `android={{ }}`), Fabric + Codegen typed bindings, Expo config plugin, TypeScript. | Four or five packages with different conventions, install steps and upgrade cadences. |
|
|
56
|
-
|
|
57
44
|
## Components
|
|
58
45
|
|
|
59
|
-
| Component
|
|
60
|
-
|
|
|
61
|
-
| **TextField**
|
|
62
|
-
| **DatePicker**
|
|
63
|
-
| **
|
|
64
|
-
| **
|
|
65
|
-
| **SegmentedControl**
|
|
66
|
-
| **
|
|
67
|
-
| **
|
|
68
|
-
| **
|
|
69
|
-
| **
|
|
46
|
+
| Component | iOS | Android | Instead of |
|
|
47
|
+
| ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
48
|
+
| [**TextField**](https://jarx-concepts.github.io/react-native-platform-components/components/textfield) | `UITextField` / `UITextView`, with Writing Tools and the iOS 17–18 text traits | Material 3 `TextInputLayout`: outlined or filled, floating label, supporting text, counter | `TextInput` (a bare `EditText` on Android); `react-native-paper` (drawn in JavaScript) |
|
|
49
|
+
| [**DatePicker**](https://jarx-concepts.github.io/react-native-platform-components/components/datepicker) | `UIDatePicker`, modal or embedded | `MaterialDatePicker` / `MaterialTimePicker`, or the AppCompat dialogs | `@react-native-community/datetimepicker` (no Material 3 pickers) |
|
|
50
|
+
| [**SelectionMenu**](https://jarx-concepts.github.io/react-native-platform-components/components/selectionmenu) | System menus | Material exposed dropdown or `Spinner` | `@react-native-picker/picker` (wheel or dialog, no menu) |
|
|
51
|
+
| [**ContextMenu**](https://jarx-concepts.github.io/react-native-platform-components/components/contextmenu) | `UIContextMenuInteraction` | `PopupMenu` | `zeego` (through two more native packages) |
|
|
52
|
+
| [**SegmentedControl**](https://jarx-concepts.github.io/react-native-platform-components/components/segmentedcontrol) | `UISegmentedControl` | Material 3 Expressive connected buttons, or classic segmented buttons | `@react-native-segmented-control/segmented-control` (JavaScript on Android) |
|
|
53
|
+
| [**TabBar**](https://jarx-concepts.github.io/react-native-platform-components/components/tabbar) | `UITabBar`, the floating Liquid Glass bar on iOS 26 | Material 3 navigation bar | React Navigation's bottom tabs (JavaScript); `react-native-bottom-tabs` (tied to its navigator) |
|
|
54
|
+
| [**NavigationRail**](https://jarx-concepts.github.io/react-native-platform-components/components/navigationrail) | A column of tab-style `UIButton`s (iOS has no rail; use TabBar on iPhone) | Material 3 Expressive `NavigationRailView`: header, badges, menu gravity, expanded rail | React Navigation's drawer or a custom view (JavaScript) |
|
|
55
|
+
| [**Button**](https://jarx-concepts.github.io/react-native-platform-components/components/button) | `UIButton` configurations, Liquid Glass variants on iOS 26 | Material 3 Expressive `MaterialButton`: five sizes, shape morph | `react-native-paper` (Material 3, not Expressive, in JavaScript) |
|
|
56
|
+
| [**ButtonGroup**](https://jarx-concepts.github.io/react-native-platform-components/components/buttongroup) | A row of `UIButton`s with a "…" overflow menu; SplitButton: a button and a chevron `UIMenu` button | Material 3 Expressive button groups, single or multiple selection, overflow menu; `MaterialSplitButton` | `react-native-paper` segmented buttons (JavaScript) |
|
|
57
|
+
| [**FloatingActionButton**](https://jarx-concepts.github.io/react-native-platform-components/components/floatingactionbutton) | A round prominent `UIButton`, Liquid Glass on iOS 26 (iOS has no FAB) | Material `FloatingActionButton` / `ExtendedFloatingActionButton`: four sizes, shrink on scroll | `react-native-paper` FAB (drawn in JavaScript) |
|
|
58
|
+
| [**FloatingToolbar**](https://jarx-concepts.github.io/react-native-platform-components/components/floatingtoolbar) | Liquid Glass capsule on iOS 26, blur before | Material 3 Expressive `FloatingToolbarLayout` | A custom view |
|
|
59
|
+
| [**LiquidGlass**](https://jarx-concepts.github.io/react-native-platform-components/components/liquidglass) | `UIGlassEffect` on iOS 26+; `LiquidGlassContainer` merges and morphs it (`UIGlassContainerEffect`) | A fallback `View` | `@callstack/liquid-glass`, `expo-glass-effect` |
|
|
60
|
+
|
|
61
|
+
One package and one API shape: platform-only props go under `ios={{ }}` and `android={{ }}`, with Fabric + Codegen typed bindings, an Expo config plugin and TypeScript, instead of four or five packages with their own conventions, install steps and upgrade cadences.
|
|
70
62
|
|
|
71
63
|
**Have a component request?** If there's a native UI component you'd like to see added, [open an issue](https://github.com/JarX-Concepts/react-native-platform-components/issues/new) describing the component and its native APIs on iOS and Android.
|
|
72
64
|
|
|
@@ -74,6 +66,16 @@ That renders `UISegmentedControl` on iOS and Material 3 segmented buttons (`Mate
|
|
|
74
66
|
|
|
75
67
|
---
|
|
76
68
|
|
|
69
|
+
## Web
|
|
70
|
+
|
|
71
|
+
Connect your existing web UI through `PlatformComponentsProvider`: register typed
|
|
72
|
+
web adapters once, then keep the same component imports, props and callbacks in
|
|
73
|
+
shared screens. Override only the controls you need; the others keep the existing
|
|
74
|
+
web fallbacks. iOS and Android continue using their native widgets.
|
|
75
|
+
|
|
76
|
+
See the [web integration guide](https://jarx-concepts.github.io/react-native-platform-components/guides/web)
|
|
77
|
+
for setup, adapter examples, field refs and current fallback limitations.
|
|
78
|
+
|
|
77
79
|
## Installation
|
|
78
80
|
|
|
79
81
|
```sh
|
|
@@ -122,10 +124,10 @@ The library is built for the New Architecture (Fabric + Codegen) and does not su
|
|
|
122
124
|
| iOS | 15.1 (LiquidGlass needs iOS 26) |
|
|
123
125
|
| Android | API 24 (Android 7.0); Material Components 1.14 is bundled |
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
26
|
|
128
|
-
CI
|
|
127
|
+
React Native 0.81 / Expo SDK 54 is the supported minimum. CI builds that
|
|
128
|
+
combination with both Xcode 26 and Xcode 16.4; Liquid Glass is compiled out
|
|
129
|
+
when the iOS 26 SDK is unavailable. Android is also built against React
|
|
130
|
+
Native 0.76 in CI to check native compatibility below the supported minimum.
|
|
129
131
|
|
|
130
132
|
Full details: [Installation](https://jarx-concepts.github.io/react-native-platform-components/installation).
|
|
131
133
|
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
package com.platformcomponents
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.content.res.ColorStateList
|
|
4
5
|
import android.text.TextUtils
|
|
5
6
|
import android.view.ContextThemeWrapper
|
|
7
|
+
import android.view.Gravity
|
|
6
8
|
import android.view.View
|
|
7
9
|
import android.view.ViewGroup.MarginLayoutParams
|
|
8
10
|
import android.widget.FrameLayout
|
|
11
|
+
import androidx.appcompat.widget.PopupMenu
|
|
12
|
+
import androidx.core.content.ContextCompat
|
|
9
13
|
import com.facebook.react.bridge.WritableNativeMap
|
|
10
14
|
import com.facebook.react.uimanager.PixelUtil
|
|
11
15
|
import com.facebook.react.uimanager.ReactCompoundViewGroup
|
|
12
16
|
import com.facebook.react.uimanager.StateWrapper
|
|
13
17
|
import com.facebook.react.views.scroll.ReactScrollViewHelper
|
|
18
|
+
import com.google.android.material.R as MaterialR
|
|
14
19
|
import com.google.android.material.button.MaterialButton
|
|
15
20
|
import com.google.android.material.button.MaterialButtonGroup
|
|
16
21
|
import com.google.android.material.button.MaterialButtonToggleGroup
|
|
22
|
+
import com.google.android.material.button.MaterialSplitButton
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* A Material 3 Expressive button group: MaterialButtonGroup for plain actions,
|
|
20
|
-
* MaterialButtonToggleGroup for single / multiple selection
|
|
21
|
-
*
|
|
26
|
+
* MaterialButtonToggleGroup for single / multiple selection, and
|
|
27
|
+
* MaterialSplitButton in split mode (SplitButton). Rebuilt whenever a prop the
|
|
28
|
+
* widgets read at construction changes.
|
|
22
29
|
*/
|
|
23
30
|
class PCButtonGroupView(context: Context) :
|
|
24
31
|
FrameLayout(context),
|
|
@@ -38,6 +45,9 @@ class PCButtonGroupView(context: Context) :
|
|
|
38
45
|
|
|
39
46
|
companion object {
|
|
40
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
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
// --- State Wrapper for Fabric state updates ---
|
|
@@ -59,6 +69,10 @@ class PCButtonGroupView(context: Context) :
|
|
|
59
69
|
var interactivity: String = "enabled" // "enabled" | "disabled"
|
|
60
70
|
var overflow: String = "none" // "none" | "menu" | "wrap"
|
|
61
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 = ""
|
|
62
76
|
|
|
63
77
|
// --- Styling (null / empty = Material theme default) ---
|
|
64
78
|
var containerColor: Int? = null
|
|
@@ -70,12 +84,19 @@ class PCButtonGroupView(context: Context) :
|
|
|
70
84
|
var labelFontWeight: String = ""
|
|
71
85
|
var labelFontStyle: String = ""
|
|
72
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
|
+
|
|
73
90
|
// --- Events ---
|
|
74
91
|
var onPress: ((index: Int, value: String) -> Unit)? = null
|
|
75
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
|
|
76
96
|
|
|
77
97
|
// --- UI ---
|
|
78
98
|
private var group: MaterialButtonGroup? = null
|
|
99
|
+
private var popupMenu: PopupMenu? = null
|
|
79
100
|
private val buttonIdToIndex: MutableMap<Int, Int> = mutableMapOf()
|
|
80
101
|
private var suppressCallbacks = false
|
|
81
102
|
private var selectionEmitPending = false
|
|
@@ -176,6 +197,22 @@ class PCButtonGroupView(context: Context) :
|
|
|
176
197
|
rebuildUI()
|
|
177
198
|
}
|
|
178
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
|
+
|
|
179
216
|
fun applyMaterial(value: String?) {
|
|
180
217
|
val parsed = PCExpressive.parseExpressive(value)
|
|
181
218
|
if (expressive == parsed) return
|
|
@@ -221,6 +258,7 @@ class PCButtonGroupView(context: Context) :
|
|
|
221
258
|
|
|
222
259
|
override fun onDetachedFromWindow() {
|
|
223
260
|
PCNativeTheme.removeListener(nativeThemeListener)
|
|
261
|
+
popupMenu?.dismiss()
|
|
224
262
|
super.onDetachedFromWindow()
|
|
225
263
|
}
|
|
226
264
|
|
|
@@ -251,7 +289,14 @@ class PCButtonGroupView(context: Context) :
|
|
|
251
289
|
val groupContext = if (overlay != 0) ContextThemeWrapper(base, overlay) else base
|
|
252
290
|
|
|
253
291
|
val g: MaterialButtonGroup =
|
|
254
|
-
if (
|
|
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) {
|
|
255
300
|
MaterialButtonToggleGroup(groupContext).apply {
|
|
256
301
|
isSingleSelection = selection == "single"
|
|
257
302
|
isSelectionRequired = selectionRequired
|
|
@@ -266,12 +311,14 @@ class PCButtonGroupView(context: Context) :
|
|
|
266
311
|
g.spacing = (spacing * resources.displayMetrics.density).toInt()
|
|
267
312
|
}
|
|
268
313
|
g.overflowMode = when (overflow) {
|
|
269
|
-
"menu" -> MaterialButtonGroup.OVERFLOW_MODE_MENU
|
|
270
|
-
"wrap" -> MaterialButtonGroup.OVERFLOW_MODE_WRAP
|
|
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
|
|
271
316
|
else -> MaterialButtonGroup.OVERFLOW_MODE_NONE
|
|
272
317
|
}
|
|
273
318
|
|
|
274
|
-
|
|
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()) {
|
|
275
322
|
val iconOnly = item.label.isEmpty() && item.icon.isPresent
|
|
276
323
|
|
|
277
324
|
val button = PCExpressive.createButton(
|
|
@@ -308,6 +355,8 @@ class PCButtonGroupView(context: Context) :
|
|
|
308
355
|
g.addView(button, params)
|
|
309
356
|
}
|
|
310
357
|
|
|
358
|
+
if (split && shown.isNotEmpty()) addSplitMenuButton(g as MaterialSplitButton, base, g.getChildAt(0) as MaterialButton)
|
|
359
|
+
|
|
311
360
|
if (g is MaterialButtonToggleGroup) {
|
|
312
361
|
g.addOnButtonCheckedListener { _, _, _ ->
|
|
313
362
|
if (suppressCallbacks) return@addOnButtonCheckedListener
|
|
@@ -325,6 +374,113 @@ class PCButtonGroupView(context: Context) :
|
|
|
325
374
|
requestLayout()
|
|
326
375
|
}
|
|
327
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
|
+
|
|
328
484
|
private fun scheduleSelectionEmit() {
|
|
329
485
|
if (selectionEmitPending) return
|
|
330
486
|
selectionEmitPending = true
|
|
@@ -341,14 +497,23 @@ class PCButtonGroupView(context: Context) :
|
|
|
341
497
|
.sorted()
|
|
342
498
|
.map { items[it].value }
|
|
343
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()
|
|
344
503
|
}
|
|
345
504
|
|
|
346
505
|
private fun updateSelection() {
|
|
347
506
|
val g = group as? MaterialButtonToggleGroup ?: return
|
|
348
507
|
suppressCallbacks = true
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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)
|
|
352
517
|
}
|
|
353
518
|
suppressCallbacks = false
|
|
354
519
|
}
|
|
@@ -363,6 +528,7 @@ class PCButtonGroupView(context: Context) :
|
|
|
363
528
|
val index = buttonIdToIndex[button.id] ?: continue
|
|
364
529
|
button.isEnabled = enabled && !items[index].disabled
|
|
365
530
|
}
|
|
531
|
+
splitMenuButton()?.isEnabled = enabled
|
|
366
532
|
}
|
|
367
533
|
|
|
368
534
|
// ---- Layout ----
|
|
@@ -3,6 +3,7 @@ package com.platformcomponents
|
|
|
3
3
|
import com.facebook.react.bridge.Arguments
|
|
4
4
|
import com.facebook.react.bridge.ReadableArray
|
|
5
5
|
import com.facebook.react.bridge.ReadableMap
|
|
6
|
+
import com.facebook.react.bridge.WritableMap
|
|
6
7
|
import com.facebook.react.uimanager.ReactStylesDiffMap
|
|
7
8
|
import com.facebook.react.uimanager.SimpleViewManager
|
|
8
9
|
import com.facebook.react.uimanager.StateWrapper
|
|
@@ -53,11 +54,23 @@ class PCButtonGroupViewManager :
|
|
|
53
54
|
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.id)
|
|
54
55
|
|
|
55
56
|
view.onPress = { index, value ->
|
|
57
|
+
PCHaptics.perform(view, view.haptics)
|
|
56
58
|
dispatcher?.dispatchEvent(PressEvent(view.id, index, value))
|
|
57
59
|
}
|
|
58
60
|
view.onSelectionChange = { values ->
|
|
59
61
|
dispatcher?.dispatchEvent(SelectionEvent(view.id, values))
|
|
60
62
|
}
|
|
63
|
+
fun dispatch(name: String, fill: WritableMap.() -> Unit = {}) {
|
|
64
|
+
dispatcher?.dispatchEvent(MenuEvent(UIManagerHelper.getSurfaceId(view), view.id, name, fill))
|
|
65
|
+
}
|
|
66
|
+
view.onMenuSelect = { id, title ->
|
|
67
|
+
dispatch("topMenuSelect") {
|
|
68
|
+
putString("id", id)
|
|
69
|
+
putString("title", title)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
view.onMenuOpen = { dispatch("topMenuOpen") }
|
|
73
|
+
view.onMenuClose = { dispatch("topMenuClose") }
|
|
61
74
|
}
|
|
62
75
|
|
|
63
76
|
// buttons: array of {label, value, disabled, iconType, iconName, iconUri,
|
|
@@ -152,9 +165,32 @@ class PCButtonGroupViewManager :
|
|
|
152
165
|
)
|
|
153
166
|
}
|
|
154
167
|
|
|
155
|
-
//
|
|
168
|
+
// "none" | "menu" | "wrap"
|
|
169
|
+
override fun setOverflow(view: PCButtonGroupView, value: String?) {
|
|
170
|
+
view.applyOverflow(value)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// "true" | "false": MaterialSplitButton
|
|
174
|
+
override fun setSplit(view: PCButtonGroupView, value: String?) {
|
|
175
|
+
view.applySplit(value == "true")
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// menu: the split button's flattened menu items
|
|
179
|
+
override fun setMenu(view: PCButtonGroupView, value: ReadableArray?) {
|
|
180
|
+
view.applyMenu(PCMenuSupport.parseItems(value))
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
override fun setMenuAccessibilityLabel(view: PCButtonGroupView, value: String?) {
|
|
184
|
+
view.applyMenuAccessibilityLabel(value ?: "")
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// "" (none added) | "none" | "selection" | "light" | "medium" | "heavy" | "success" | "warning" | "error"
|
|
188
|
+
override fun setHaptics(view: PCButtonGroupView, value: String?) {
|
|
189
|
+
view.haptics = PCHaptics.configure(view, value)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// android: {material}
|
|
156
193
|
override fun setAndroid(view: PCButtonGroupView, value: ReadableMap?) {
|
|
157
|
-
view.applyOverflow(value?.stringOr("overflow", "none"))
|
|
158
194
|
view.applyMaterial(value?.stringOr("material", "expressive"))
|
|
159
195
|
}
|
|
160
196
|
|
|
@@ -174,6 +210,20 @@ class PCButtonGroupViewManager :
|
|
|
174
210
|
}
|
|
175
211
|
}
|
|
176
212
|
|
|
213
|
+
private class MenuEvent(
|
|
214
|
+
surfaceId: Int,
|
|
215
|
+
viewTag: Int,
|
|
216
|
+
private val name: String,
|
|
217
|
+
private val fill: WritableMap.() -> Unit
|
|
218
|
+
) : Event<MenuEvent>(surfaceId, viewTag) {
|
|
219
|
+
override fun canCoalesce(): Boolean = false
|
|
220
|
+
|
|
221
|
+
override fun getEventName(): String = name
|
|
222
|
+
|
|
223
|
+
// Fabric reads the payload from here
|
|
224
|
+
override fun getEventData(): WritableMap = Arguments.createMap().apply(fill)
|
|
225
|
+
}
|
|
226
|
+
|
|
177
227
|
private class SelectionEvent(
|
|
178
228
|
surfaceId: Int,
|
|
179
229
|
private val values: List<String>
|
|
@@ -3,6 +3,7 @@ package com.platformcomponents
|
|
|
3
3
|
import android.content.res.ColorStateList
|
|
4
4
|
import android.graphics.Color
|
|
5
5
|
import android.graphics.drawable.BitmapDrawable
|
|
6
|
+
import android.os.Build
|
|
6
7
|
import android.util.TypedValue
|
|
7
8
|
import android.widget.TextView
|
|
8
9
|
import com.facebook.react.bridge.ReadableMap
|
|
@@ -18,7 +19,8 @@ object PCButtonSupport {
|
|
|
18
19
|
val name: String,
|
|
19
20
|
val uri: String,
|
|
20
21
|
val scale: Float,
|
|
21
|
-
val tinted: Boolean
|
|
22
|
+
val tinted: Boolean,
|
|
23
|
+
val request: String = ""
|
|
22
24
|
) {
|
|
23
25
|
val isPresent: Boolean get() = type == "drawable" || type == "image"
|
|
24
26
|
}
|
|
@@ -40,7 +42,8 @@ object PCButtonSupport {
|
|
|
40
42
|
name = map.stringOr("iconName", ""),
|
|
41
43
|
uri = map.stringOr("iconUri", ""),
|
|
42
44
|
scale = if (scale > 0) scale.toFloat() else 1f,
|
|
43
|
-
tinted = map.stringOr("iconTinted", "true") != "false"
|
|
45
|
+
tinted = map.stringOr("iconTinted", "true") != "false",
|
|
46
|
+
request = map.stringOr("iconRequest", "")
|
|
44
47
|
)
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -64,7 +67,7 @@ object PCButtonSupport {
|
|
|
64
67
|
if (!uri.contains(':')) {
|
|
65
68
|
button.icon = ResourceDrawableIdHelper.instance.getResourceDrawable(context, uri)
|
|
66
69
|
} else {
|
|
67
|
-
PCImageLoader.load(context, uri, icon.scale) { bitmap ->
|
|
70
|
+
PCImageLoader.load(context, uri, icon.scale, icon.request) { bitmap ->
|
|
68
71
|
if (bitmap == null || !isCurrent()) return@load
|
|
69
72
|
button.icon = BitmapDrawable(context.resources, bitmap)
|
|
70
73
|
onLoaded()
|
|
@@ -91,8 +94,28 @@ object PCButtonSupport {
|
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
97
|
+
* Caps the label's font scaling at [maxMultiplier] times its unscaled size,
|
|
98
|
+
* as React Native's maxFontSizeMultiplier does; below 1 means no cap. Call
|
|
99
|
+
* after the font size is set.
|
|
100
|
+
*/
|
|
101
|
+
fun applyMaxFontSizeMultiplier(button: TextView, maxMultiplier: Float) {
|
|
102
|
+
if (maxMultiplier < 1f) return
|
|
103
|
+
val metrics = button.resources.displayMetrics
|
|
104
|
+
// The sp size back from pixels; Android 14+ scales large text non-linearly
|
|
105
|
+
val sp = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
106
|
+
TypedValue.deriveDimension(TypedValue.COMPLEX_UNIT_SP, button.textSize, metrics)
|
|
107
|
+
} else {
|
|
108
|
+
button.textSize / (metrics.density * button.resources.configuration.fontScale)
|
|
109
|
+
}
|
|
110
|
+
val cap = sp * metrics.density * maxMultiplier
|
|
111
|
+
if (button.textSize > cap) {
|
|
112
|
+
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, cap)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Applies the color props on top of the style's colors. Unset disabled
|
|
118
|
+
* colors keep the style's; unset enabled colors keep the style's too.
|
|
96
119
|
*/
|
|
97
120
|
fun applyColors(
|
|
98
121
|
button: MaterialButton,
|
|
@@ -100,21 +123,30 @@ object PCButtonSupport {
|
|
|
100
123
|
foreground: Int?,
|
|
101
124
|
ripple: Int?,
|
|
102
125
|
stroke: Int?,
|
|
103
|
-
iconTinted: Boolean
|
|
126
|
+
iconTinted: Boolean,
|
|
127
|
+
disabledContainer: Int? = null,
|
|
128
|
+
disabledForeground: Int? = null
|
|
104
129
|
) {
|
|
105
130
|
val disabledState = intArrayOf(-android.R.attr.state_enabled)
|
|
131
|
+
val enabledState = intArrayOf(android.R.attr.state_enabled)
|
|
106
132
|
val states = arrayOf(disabledState, intArrayOf())
|
|
107
133
|
|
|
108
|
-
container
|
|
134
|
+
if (container != null || disabledContainer != null) {
|
|
109
135
|
val theme = button.backgroundTintList
|
|
110
|
-
val disabled =
|
|
111
|
-
|
|
136
|
+
val disabled = disabledContainer
|
|
137
|
+
?: theme?.getColorForState(disabledState, theme.defaultColor)
|
|
138
|
+
?: Color.TRANSPARENT
|
|
139
|
+
val enabled = container
|
|
140
|
+
?: theme?.getColorForState(enabledState, theme.defaultColor)
|
|
141
|
+
?: Color.TRANSPARENT
|
|
142
|
+
button.backgroundTintList = ColorStateList(states, intArrayOf(disabled, enabled))
|
|
112
143
|
}
|
|
113
144
|
|
|
114
|
-
foreground
|
|
145
|
+
if (foreground != null || disabledForeground != null) {
|
|
115
146
|
val theme = button.textColors
|
|
116
|
-
val disabled = theme.getColorForState(disabledState, theme.defaultColor)
|
|
117
|
-
val
|
|
147
|
+
val disabled = disabledForeground ?: theme.getColorForState(disabledState, theme.defaultColor)
|
|
148
|
+
val enabled = foreground ?: theme.getColorForState(enabledState, theme.defaultColor)
|
|
149
|
+
val tint = ColorStateList(states, intArrayOf(disabled, enabled))
|
|
118
150
|
button.setTextColor(tint)
|
|
119
151
|
if (iconTinted) {
|
|
120
152
|
button.iconTint = tint
|