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