react-native-platform-components 1.4.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 +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.d.ts +3 -2
- package/plugin/build/index.d.ts.map +1 -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
|
@@ -1,30 +1,58 @@
|
|
|
1
1
|
package com.platformcomponents
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.content.res.ColorStateList
|
|
5
|
+
import android.graphics.drawable.ColorDrawable
|
|
6
|
+
import android.graphics.drawable.Drawable
|
|
7
|
+
import android.graphics.drawable.RippleDrawable
|
|
4
8
|
import android.text.InputType
|
|
9
|
+
import android.text.TextUtils
|
|
5
10
|
import android.util.Log
|
|
11
|
+
import android.util.TypedValue
|
|
12
|
+
import android.view.Gravity
|
|
6
13
|
import android.view.View
|
|
7
14
|
import android.view.ViewGroup
|
|
8
15
|
import android.view.ViewTreeObserver
|
|
16
|
+
import android.view.inputmethod.EditorInfo
|
|
17
|
+
import android.view.inputmethod.InputMethodManager
|
|
9
18
|
import android.widget.AdapterView
|
|
10
19
|
import android.widget.ArrayAdapter
|
|
20
|
+
import android.widget.BaseAdapter
|
|
21
|
+
import android.widget.Filter
|
|
22
|
+
import android.widget.Filterable
|
|
11
23
|
import android.widget.FrameLayout
|
|
24
|
+
import android.widget.ImageView
|
|
12
25
|
import android.widget.LinearLayout
|
|
13
26
|
import android.widget.Spinner
|
|
27
|
+
import android.widget.TextView
|
|
14
28
|
import androidx.appcompat.widget.PopupMenu
|
|
29
|
+
import androidx.core.widget.TextViewCompat
|
|
15
30
|
import com.facebook.react.bridge.WritableNativeMap
|
|
16
31
|
import com.facebook.react.uimanager.PixelUtil
|
|
17
32
|
import com.facebook.react.uimanager.StateWrapper
|
|
18
33
|
import com.facebook.react.views.scroll.ReactScrollViewHelper
|
|
34
|
+
import com.google.android.material.R as MaterialR
|
|
35
|
+
import com.google.android.material.color.MaterialColors
|
|
19
36
|
import com.google.android.material.textfield.MaterialAutoCompleteTextView
|
|
20
37
|
import com.google.android.material.textfield.TextInputLayout
|
|
38
|
+
import java.util.Locale
|
|
21
39
|
|
|
22
40
|
class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollViewHelper.HasStateWrapper {
|
|
23
41
|
|
|
24
|
-
data class Option(
|
|
42
|
+
data class Option(
|
|
43
|
+
val label: String,
|
|
44
|
+
val data: String,
|
|
45
|
+
val subtitle: String = "",
|
|
46
|
+
val icon: PCButtonSupport.Icon = PCButtonSupport.NO_ICON,
|
|
47
|
+
val disabled: Boolean = false
|
|
48
|
+
) {
|
|
49
|
+
/** Has content beyond a label, which needs the rich dropdown rows. */
|
|
50
|
+
val isRich: Boolean get() = subtitle.isNotEmpty() || icon.isPresent
|
|
51
|
+
}
|
|
25
52
|
|
|
26
53
|
companion object {
|
|
27
54
|
private const val TAG = "PCSelectionMenu"
|
|
55
|
+
private const val HEADLESS_GROUP_ID = 0
|
|
28
56
|
}
|
|
29
57
|
|
|
30
58
|
// --- State Wrapper for Fabric state updates ---
|
|
@@ -46,6 +74,12 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
46
74
|
// Only used to choose inline rendering style.
|
|
47
75
|
var androidMaterial: String? = "system" // "system" | "m3"
|
|
48
76
|
|
|
77
|
+
// Embedded M3 only: the field accepts typing and filters the options.
|
|
78
|
+
var androidSearchable: Boolean = false
|
|
79
|
+
|
|
80
|
+
/** The `haptics` prop; the manager plays it with the user's action (see PCHaptics). */
|
|
81
|
+
var haptics: String = ""
|
|
82
|
+
|
|
49
83
|
// --- Events ---
|
|
50
84
|
var onSelect: ((index: Int, label: String, data: String) -> Unit)? = null
|
|
51
85
|
var onRequestClose: (() -> Unit)? = null
|
|
@@ -56,6 +90,8 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
56
90
|
private var inlineSpinner: Spinner? = null
|
|
57
91
|
private var inlineDropdownOverlay: View? = null
|
|
58
92
|
private var inlineSpinnerSuppressCount = 0
|
|
93
|
+
private var inlineSpinnerPendingSelection: String? = null
|
|
94
|
+
private var inlineSpinnerHasPlaceholder = false
|
|
59
95
|
|
|
60
96
|
// --- Headless UI (true picker) ---
|
|
61
97
|
private var headlessMenu: PopupMenu? = null
|
|
@@ -232,7 +268,7 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
232
268
|
val next = data ?: ""
|
|
233
269
|
if (selectedData == next) return
|
|
234
270
|
selectedData = next
|
|
235
|
-
Log.d(TAG, "applySelectedData
|
|
271
|
+
Log.d(TAG, "applySelectedData")
|
|
236
272
|
refreshSelections()
|
|
237
273
|
}
|
|
238
274
|
|
|
@@ -257,7 +293,10 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
257
293
|
if (placeholder == value) return
|
|
258
294
|
placeholder = value
|
|
259
295
|
inlineLayout?.hint = placeholder
|
|
260
|
-
|
|
296
|
+
if (inlineSpinner != null) {
|
|
297
|
+
refreshAdapters()
|
|
298
|
+
refreshSelections()
|
|
299
|
+
}
|
|
261
300
|
|
|
262
301
|
// Re-measure after placeholder change
|
|
263
302
|
if (anchorMode == "inline") {
|
|
@@ -312,6 +351,16 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
312
351
|
if (anchorMode == "inline") rebuildUI()
|
|
313
352
|
}
|
|
314
353
|
|
|
354
|
+
fun applyAndroidSearchable(value: Boolean) {
|
|
355
|
+
if (androidSearchable == value) return
|
|
356
|
+
androidSearchable = value
|
|
357
|
+
if (anchorMode == "inline" && parseMaterial(androidMaterial) == MaterialMode.M3) rebuildUI()
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/** The embedded M3 field takes typing to filter the options. */
|
|
361
|
+
private val isSearchable: Boolean
|
|
362
|
+
get() = androidSearchable && anchorMode == "inline" && parseMaterial(androidMaterial) == MaterialMode.M3
|
|
363
|
+
|
|
315
364
|
// ---- UI building ----
|
|
316
365
|
|
|
317
366
|
private fun rebuildUI() {
|
|
@@ -328,6 +377,8 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
328
377
|
inlineText = null
|
|
329
378
|
inlineSpinner = null
|
|
330
379
|
inlineSpinnerSuppressCount = 0
|
|
380
|
+
inlineSpinnerPendingSelection = null
|
|
381
|
+
inlineSpinnerHasPlaceholder = false
|
|
331
382
|
headlessMenu = null
|
|
332
383
|
headlessMenuShowing = false
|
|
333
384
|
headlessDismissProgrammatic = false
|
|
@@ -387,24 +438,58 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
387
438
|
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
388
439
|
)
|
|
389
440
|
|
|
390
|
-
|
|
391
|
-
|
|
441
|
+
if (isSearchable) {
|
|
442
|
+
// Typing filters the options (see OptionAdapter). The text is only a
|
|
443
|
+
// query: selection still comes from picking an option.
|
|
444
|
+
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
|
|
445
|
+
imeOptions = EditorInfo.IME_ACTION_DONE
|
|
446
|
+
// The first tap selects the label, so typing replaces it
|
|
447
|
+
setSelectAllOnFocus(true)
|
|
448
|
+
setOnEditorActionListener { _, actionId, _ ->
|
|
449
|
+
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
|
450
|
+
clearFocus()
|
|
451
|
+
true
|
|
452
|
+
} else {
|
|
453
|
+
false
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
} else {
|
|
457
|
+
// Keep it a real text editor so the popup behaves modally
|
|
458
|
+
inputType = InputType.TYPE_CLASS_TEXT
|
|
459
|
+
|
|
460
|
+
// Prevent keyboard
|
|
461
|
+
showSoftInputOnFocus = false
|
|
392
462
|
|
|
393
|
-
|
|
394
|
-
|
|
463
|
+
// Optional: keep it from being typed into
|
|
464
|
+
keyListener = null
|
|
465
|
+
isCursorVisible = false
|
|
466
|
+
}
|
|
395
467
|
|
|
396
|
-
//
|
|
397
|
-
|
|
398
|
-
|
|
468
|
+
// Highlight the selected option in the dropdown, like the M3 exposed dropdown menu.
|
|
469
|
+
// The adapter from setSimpleItems() marks the item whose text matches the field.
|
|
470
|
+
simpleItemSelectedColor = MaterialColors.getColor(
|
|
471
|
+
til.context,
|
|
472
|
+
com.google.android.material.R.attr.colorSecondaryContainer,
|
|
473
|
+
0
|
|
474
|
+
)
|
|
399
475
|
|
|
400
476
|
// Nice UX: click anywhere opens dropdown
|
|
401
477
|
setOnClickListener { showDropDown() }
|
|
402
478
|
|
|
403
479
|
setOnItemClickListener { _, _, position, _ ->
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
480
|
+
// A filtered list's positions differ from the options'
|
|
481
|
+
val opt = (adapter as? OptionAdapter)?.getItem(position)
|
|
482
|
+
?: options.getOrNull(position)
|
|
483
|
+
?: return@setOnItemClickListener
|
|
484
|
+
val index = options.indexOf(opt)
|
|
485
|
+
if (interactivity != "enabled" || opt.disabled) {
|
|
486
|
+
post { refreshSelections() }
|
|
487
|
+
return@setOnItemClickListener
|
|
488
|
+
}
|
|
489
|
+
onSelect?.invoke(index, opt.label, opt.data)
|
|
490
|
+
post { refreshSelections() }
|
|
407
491
|
detachInlineDropdownOverlay()
|
|
492
|
+
if (isSearchable) clearFocus()
|
|
408
493
|
}
|
|
409
494
|
|
|
410
495
|
setOnTouchListener { _, e ->
|
|
@@ -416,6 +501,21 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
416
501
|
}
|
|
417
502
|
|
|
418
503
|
til.addView(actv)
|
|
504
|
+
if (isSearchable) {
|
|
505
|
+
// Set after the field joins the layout, whose dropdown icon installs its
|
|
506
|
+
// own focus listener; that one still runs first.
|
|
507
|
+
val materialFocusListener = actv.onFocusChangeListener
|
|
508
|
+
actv.setOnFocusChangeListener { view, hasFocus ->
|
|
509
|
+
materialFocusListener?.onFocusChange(view, hasFocus)
|
|
510
|
+
if (hasFocus) return@setOnFocusChangeListener
|
|
511
|
+
// Leaving the field: the query goes, and the field shows the
|
|
512
|
+
// selected option again (or the placeholder)
|
|
513
|
+
actv.dismissDropDown()
|
|
514
|
+
showSelectedText()
|
|
515
|
+
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
|
516
|
+
imm?.hideSoftInputFromWindow(view.windowToken, 0)
|
|
517
|
+
}
|
|
518
|
+
}
|
|
419
519
|
addView(til)
|
|
420
520
|
inlineLayout = til
|
|
421
521
|
} else {
|
|
@@ -423,6 +523,7 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
423
523
|
val sp = object : Spinner(context, null, android.R.attr.spinnerStyle, Spinner.MODE_DROPDOWN) {
|
|
424
524
|
override fun setSelection(position: Int, animate: Boolean) {
|
|
425
525
|
val oldPos = selectedItemPosition
|
|
526
|
+
val selectionAdapter = adapter
|
|
426
527
|
super.setSelection(position, animate)
|
|
427
528
|
|
|
428
529
|
// Manually trigger onItemSelectedListener if selection changed
|
|
@@ -430,6 +531,7 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
430
531
|
// the selection changes via user interaction with the dropdown
|
|
431
532
|
if (position != oldPos && onItemSelectedListener != null) {
|
|
432
533
|
post {
|
|
534
|
+
if (adapter !== selectionAdapter || selectedItemPosition != position) return@post
|
|
433
535
|
onItemSelectedListener?.onItemSelected(
|
|
434
536
|
this,
|
|
435
537
|
selectedView,
|
|
@@ -442,11 +544,13 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
442
544
|
|
|
443
545
|
override fun setSelection(position: Int) {
|
|
444
546
|
val oldPos = selectedItemPosition
|
|
547
|
+
val selectionAdapter = adapter
|
|
445
548
|
super.setSelection(position)
|
|
446
549
|
|
|
447
550
|
// Manually trigger onItemSelectedListener if selection changed
|
|
448
551
|
if (position != oldPos && onItemSelectedListener != null) {
|
|
449
552
|
post {
|
|
553
|
+
if (adapter !== selectionAdapter || selectedItemPosition != position) return@post
|
|
450
554
|
onItemSelectedListener?.onItemSelected(
|
|
451
555
|
this,
|
|
452
556
|
selectedView,
|
|
@@ -470,15 +574,31 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
470
574
|
if (inlineSpinnerSuppressCount > 0) return
|
|
471
575
|
|
|
472
576
|
if (interactivity != "enabled") return
|
|
473
|
-
|
|
474
|
-
|
|
577
|
+
// Spinner can notify both synchronously and on its next layout; the
|
|
578
|
+
// fallback in setSelection must not duplicate a single user selection.
|
|
579
|
+
if (position != sp.selectedItemPosition) return
|
|
580
|
+
|
|
581
|
+
val index = position - if (inlineSpinnerHasPlaceholder) 1 else 0
|
|
582
|
+
val opt = options.getOrNull(index) ?: return
|
|
583
|
+
if (opt.disabled) {
|
|
584
|
+
post { refreshSelections() }
|
|
585
|
+
return
|
|
586
|
+
}
|
|
475
587
|
|
|
476
588
|
// Only fire callback if selection actually changed
|
|
477
589
|
if (opt.data == selectedData) return
|
|
590
|
+
if (inlineSpinnerPendingSelection == opt.data) return
|
|
591
|
+
inlineSpinnerPendingSelection = opt.data
|
|
478
592
|
|
|
479
593
|
// Don't update selectedData here - let applySelectedData handle it
|
|
480
594
|
// This ensures refreshSelections() is called to update the Spinner's display
|
|
481
|
-
onSelect?.invoke(
|
|
595
|
+
onSelect?.invoke(index, opt.label, opt.data)
|
|
596
|
+
post {
|
|
597
|
+
if (inlineSpinner === sp) {
|
|
598
|
+
refreshSelections()
|
|
599
|
+
inlineSpinnerPendingSelection = null
|
|
600
|
+
}
|
|
601
|
+
}
|
|
482
602
|
}
|
|
483
603
|
|
|
484
604
|
override fun onNothingSelected(parent: AdapterView<*>) {
|
|
@@ -503,11 +623,10 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
503
623
|
val popup = PopupMenu(context, this@PCSelectionMenuView).apply {
|
|
504
624
|
setOnMenuItemClickListener { item ->
|
|
505
625
|
val index = item.itemId
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
)
|
|
626
|
+
if (interactivity != "enabled" || options.getOrNull(index)?.disabled != false) {
|
|
627
|
+
return@setOnMenuItemClickListener false
|
|
628
|
+
}
|
|
629
|
+
Log.d(TAG, "headless onMenuItemClick index=$index")
|
|
511
630
|
headlessDismissAfterSelect = true
|
|
512
631
|
handleHeadlessSelection(index)
|
|
513
632
|
true
|
|
@@ -540,15 +659,53 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
540
659
|
|
|
541
660
|
private fun refreshAdapters() {
|
|
542
661
|
val labels = options.map { it.label }
|
|
662
|
+
val rich = options.any { it.isRich }
|
|
543
663
|
|
|
544
664
|
inlineText?.let { actv ->
|
|
545
|
-
|
|
546
|
-
|
|
665
|
+
if (rich || isSearchable || options.any { it.disabled }) {
|
|
666
|
+
// Icon + label + subtitle rows, filtered by the typed query
|
|
667
|
+
actv.setAdapter(OptionAdapter(actv.context, options))
|
|
668
|
+
} else {
|
|
669
|
+
// Material's simple-item adapter highlights the selected option (simpleItemSelectedColor).
|
|
670
|
+
actv.setSimpleItems(labels.toTypedArray())
|
|
671
|
+
}
|
|
547
672
|
}
|
|
548
673
|
|
|
549
674
|
inlineSpinner?.let { sp ->
|
|
550
675
|
suppressInlineSpinnerCallbacks(sp)
|
|
551
|
-
|
|
676
|
+
// The platform Spinner keeps its own rows (labels only): its dropdown is
|
|
677
|
+
// sized to its widest row and anchored at the field's start, so rich
|
|
678
|
+
// rows would run off the screen's edge.
|
|
679
|
+
// Spinner needs a selected row even for null. Use a normal disabled
|
|
680
|
+
// placeholder until a value is selected, then show only real options.
|
|
681
|
+
// ListView measures zero-height rows with UNSPECIFIED height, so a GONE
|
|
682
|
+
// placeholder can leave a full-height row with unreliable touch bounds.
|
|
683
|
+
val hasPlaceholder = options.none { it.data == selectedData }
|
|
684
|
+
inlineSpinnerHasPlaceholder = hasPlaceholder
|
|
685
|
+
val adapter = object : ArrayAdapter<String>(
|
|
686
|
+
sp.context, android.R.layout.simple_spinner_item,
|
|
687
|
+
if (hasPlaceholder) listOf(placeholder.orEmpty()) + labels else labels
|
|
688
|
+
) {
|
|
689
|
+
override fun areAllItemsEnabled() = !hasPlaceholder && options.none { it.disabled }
|
|
690
|
+
|
|
691
|
+
// https://developer.android.com/reference/android/widget/BaseAdapter#isEnabled(int)
|
|
692
|
+
override fun isEnabled(position: Int) =
|
|
693
|
+
options.getOrNull(position - if (hasPlaceholder) 1 else 0)?.disabled == false
|
|
694
|
+
|
|
695
|
+
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
|
|
696
|
+
val enabled = isEnabled(position)
|
|
697
|
+
return super.getDropDownView(position, convertView, parent).apply {
|
|
698
|
+
isEnabled = enabled
|
|
699
|
+
alpha = if (enabled) 1f else 0.38f
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View =
|
|
704
|
+
(super.getView(position, convertView, parent) as TextView).apply {
|
|
705
|
+
if (hasPlaceholder && position == 0) text = ""
|
|
706
|
+
hint = if (hasPlaceholder && position == 0) placeholder else null
|
|
707
|
+
}
|
|
708
|
+
}
|
|
552
709
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
|
553
710
|
sp.adapter = adapter
|
|
554
711
|
}
|
|
@@ -564,19 +721,12 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
564
721
|
private fun refreshSelections() {
|
|
565
722
|
val idx = options.indexOfFirst { it.data == selectedData }
|
|
566
723
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
// Show selected value
|
|
570
|
-
actv.setText(options[idx].label, false)
|
|
571
|
-
} else {
|
|
572
|
-
// Clear text to show placeholder
|
|
573
|
-
actv.setText("", false)
|
|
574
|
-
}
|
|
575
|
-
}
|
|
724
|
+
// A searchable field keeps the user's query while it has focus
|
|
725
|
+
if (!(isSearchable && inlineText?.hasFocus() == true)) showSelectedText()
|
|
576
726
|
|
|
577
727
|
inlineSpinner?.let { sp ->
|
|
578
|
-
if (
|
|
579
|
-
val target = if (
|
|
728
|
+
if (inlineSpinnerHasPlaceholder != (idx < 0)) refreshAdapters()
|
|
729
|
+
val target = if (inlineSpinnerHasPlaceholder) 0 else idx
|
|
580
730
|
// Always call setSelection to ensure the view is refreshed
|
|
581
731
|
// Even if the position hasn't changed, we need to update the displayed text
|
|
582
732
|
suppressInlineSpinnerCallbacks(sp)
|
|
@@ -592,6 +742,176 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
592
742
|
}
|
|
593
743
|
}
|
|
594
744
|
|
|
745
|
+
/** The embedded M3 field shows the selected option's label, or empty for the placeholder. */
|
|
746
|
+
private fun showSelectedText() {
|
|
747
|
+
val actv = inlineText ?: return
|
|
748
|
+
val label = options.firstOrNull { it.data == selectedData }?.label ?: ""
|
|
749
|
+
actv.setText(label, false)
|
|
750
|
+
// The next open lists every option until the user types again
|
|
751
|
+
(actv.adapter as? OptionAdapter)?.resetFilter()
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// ---- Rich dropdown rows ----
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Rows for the M3 exposed dropdown when options have icons or subtitles, or
|
|
758
|
+
* the field is searchable: a leading icon, the label and a second line,
|
|
759
|
+
* laid out like a Material list item. The selected row is highlighted like
|
|
760
|
+
* Material's simple items, and the list filters by the typed query (a
|
|
761
|
+
* case-insensitive prefix of the label or of any word in it, as
|
|
762
|
+
* ArrayAdapter does).
|
|
763
|
+
*/
|
|
764
|
+
private inner class OptionAdapter(
|
|
765
|
+
private val themed: Context,
|
|
766
|
+
private val all: List<Option>
|
|
767
|
+
) : BaseAdapter(), Filterable {
|
|
768
|
+
private var shown: List<Option> = all
|
|
769
|
+
private val showsIcons = all.any { it.icon.isPresent }
|
|
770
|
+
private val icons = HashMap<Int, Drawable?>()
|
|
771
|
+
private val density = themed.resources.displayMetrics.density
|
|
772
|
+
|
|
773
|
+
init {
|
|
774
|
+
// Resolve icons up front; ones that load in the background redraw the list
|
|
775
|
+
all.forEachIndexed { index, option ->
|
|
776
|
+
if (!option.icon.isPresent) return@forEachIndexed
|
|
777
|
+
var sync = true
|
|
778
|
+
PCMenuSupport.loadIcon(themed, option.icon) { drawable ->
|
|
779
|
+
icons[index] = drawable
|
|
780
|
+
if (!sync) notifyDataSetChanged()
|
|
781
|
+
}
|
|
782
|
+
sync = false
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
fun resetFilter() {
|
|
787
|
+
if (shown === all) return
|
|
788
|
+
shown = all
|
|
789
|
+
notifyDataSetChanged()
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
override fun getCount(): Int = shown.size
|
|
793
|
+
override fun getItem(position: Int): Option? = shown.getOrNull(position)
|
|
794
|
+
override fun getItemId(position: Int): Long = position.toLong()
|
|
795
|
+
override fun areAllItemsEnabled(): Boolean = shown.none { it.disabled }
|
|
796
|
+
override fun isEnabled(position: Int): Boolean = shown.getOrNull(position)?.disabled == false
|
|
797
|
+
|
|
798
|
+
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
|
799
|
+
val option = shown[position]
|
|
800
|
+
val holder = (convertView?.tag as? RowHolder) ?: RowHolder()
|
|
801
|
+
val selected = option.data == selectedData && selectedData.isNotEmpty()
|
|
802
|
+
|
|
803
|
+
holder.icon.visibility = if (showsIcons) View.VISIBLE else View.GONE
|
|
804
|
+
holder.icon.setImageDrawable(icons[all.indexOf(option)])
|
|
805
|
+
holder.label.text = option.label
|
|
806
|
+
holder.subtitle.text = option.subtitle
|
|
807
|
+
holder.subtitle.visibility = if (option.subtitle.isEmpty()) View.GONE else View.VISIBLE
|
|
808
|
+
holder.root.minimumHeight = dp(if (option.subtitle.isEmpty()) 48 else 64)
|
|
809
|
+
holder.root.background = if (selected) selectedBackground() else itemBackground()
|
|
810
|
+
holder.root.isSelected = selected
|
|
811
|
+
holder.root.isEnabled = !option.disabled
|
|
812
|
+
holder.label.isEnabled = !option.disabled
|
|
813
|
+
holder.subtitle.isEnabled = !option.disabled
|
|
814
|
+
holder.root.alpha = if (option.disabled) 0.38f else 1f
|
|
815
|
+
return holder.root
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
private fun dp(value: Int): Int = (value * density).toInt()
|
|
819
|
+
|
|
820
|
+
private fun selectedBackground(): Drawable {
|
|
821
|
+
val color = MaterialColors.getColor(themed, MaterialR.attr.colorSecondaryContainer, 0)
|
|
822
|
+
val ripple = MaterialColors.getColor(themed, MaterialR.attr.colorOnSecondaryContainer, 0)
|
|
823
|
+
return RippleDrawable(
|
|
824
|
+
ColorStateList.valueOf(ripple and 0x1FFFFFFF),
|
|
825
|
+
ColorDrawable(color),
|
|
826
|
+
null
|
|
827
|
+
)
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
private fun itemBackground(): Drawable? {
|
|
831
|
+
val value = TypedValue()
|
|
832
|
+
if (!themed.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)) return null
|
|
833
|
+
return themed.getDrawable(value.resourceId)
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
private fun textAppearance(attr: Int, fallback: Int): Int {
|
|
837
|
+
val value = TypedValue()
|
|
838
|
+
return if (themed.theme.resolveAttribute(attr, value, true) && value.resourceId != 0) {
|
|
839
|
+
value.resourceId
|
|
840
|
+
} else {
|
|
841
|
+
fallback
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
private inner class RowHolder {
|
|
846
|
+
val icon = ImageView(themed).apply {
|
|
847
|
+
layoutParams = LinearLayout.LayoutParams(dp(24), dp(24)).apply { marginEnd = dp(16) }
|
|
848
|
+
scaleType = ImageView.ScaleType.FIT_CENTER
|
|
849
|
+
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
850
|
+
}
|
|
851
|
+
val label = TextView(themed).apply {
|
|
852
|
+
TextViewCompat.setTextAppearance(
|
|
853
|
+
this,
|
|
854
|
+
textAppearance(MaterialR.attr.textAppearanceBodyLarge, android.R.style.TextAppearance_Material_Subhead)
|
|
855
|
+
)
|
|
856
|
+
maxLines = 1
|
|
857
|
+
ellipsize = TextUtils.TruncateAt.END
|
|
858
|
+
}
|
|
859
|
+
val subtitle = TextView(themed).apply {
|
|
860
|
+
TextViewCompat.setTextAppearance(
|
|
861
|
+
this,
|
|
862
|
+
textAppearance(MaterialR.attr.textAppearanceBodyMedium, android.R.style.TextAppearance_Material_Body1)
|
|
863
|
+
)
|
|
864
|
+
MaterialColors.getColor(themed, MaterialR.attr.colorOnSurfaceVariant, 0)
|
|
865
|
+
.takeIf { it != 0 }
|
|
866
|
+
?.let { setTextColor(it) }
|
|
867
|
+
maxLines = 1
|
|
868
|
+
ellipsize = TextUtils.TruncateAt.END
|
|
869
|
+
}
|
|
870
|
+
val root = LinearLayout(themed).apply {
|
|
871
|
+
orientation = LinearLayout.HORIZONTAL
|
|
872
|
+
gravity = Gravity.CENTER_VERTICAL
|
|
873
|
+
setPaddingRelative(dp(16), dp(8), dp(16), dp(8))
|
|
874
|
+
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
|
875
|
+
addView(icon)
|
|
876
|
+
addView(
|
|
877
|
+
LinearLayout(themed).apply {
|
|
878
|
+
orientation = LinearLayout.VERTICAL
|
|
879
|
+
layoutParams = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
|
|
880
|
+
addView(label)
|
|
881
|
+
addView(subtitle)
|
|
882
|
+
}
|
|
883
|
+
)
|
|
884
|
+
tag = this@RowHolder
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
override fun getFilter(): Filter = object : Filter() {
|
|
889
|
+
override fun performFiltering(constraint: CharSequence?): FilterResults {
|
|
890
|
+
val query = constraint?.toString()?.trim()?.lowercase(Locale.getDefault()).orEmpty()
|
|
891
|
+
val matches = if (!isSearchable || query.isEmpty()) all else all.filter { matches(it.label, query) }
|
|
892
|
+
return FilterResults().apply {
|
|
893
|
+
values = matches
|
|
894
|
+
count = matches.size
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
@Suppress("UNCHECKED_CAST")
|
|
899
|
+
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
|
|
900
|
+
shown = (results?.values as? List<Option>) ?: all
|
|
901
|
+
if (shown.isNotEmpty()) notifyDataSetChanged() else notifyDataSetInvalidated()
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
override fun convertResultToString(resultValue: Any?): CharSequence =
|
|
905
|
+
(resultValue as? Option)?.label ?: ""
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/** ArrayAdapter's rule: the label, or one of its words, starts with the query. */
|
|
909
|
+
private fun matches(label: String, query: String): Boolean {
|
|
910
|
+
val lower = label.lowercase(Locale.getDefault())
|
|
911
|
+
return lower.startsWith(query) || lower.split(' ').any { it.startsWith(query) }
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
595
915
|
// ---- Inline dropdown overlay ----
|
|
596
916
|
|
|
597
917
|
private inner class InlineAutoCompleteTextView(context: Context) :
|
|
@@ -629,6 +949,8 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
629
949
|
if (event.action == android.view.MotionEvent.ACTION_DOWN) {
|
|
630
950
|
inlineText?.dismissDropDown()
|
|
631
951
|
detachInlineDropdownOverlay()
|
|
952
|
+
// A tap outside also leaves a searchable field
|
|
953
|
+
if (isSearchable) inlineText?.clearFocus()
|
|
632
954
|
}
|
|
633
955
|
true
|
|
634
956
|
}
|
|
@@ -695,8 +1017,8 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
695
1017
|
|
|
696
1018
|
private fun handleHeadlessSelection(position: Int) {
|
|
697
1019
|
val opt = options.getOrNull(position) ?: return
|
|
698
|
-
|
|
699
|
-
|
|
1020
|
+
if (interactivity != "enabled" || opt.disabled) return
|
|
1021
|
+
Log.d(TAG, "handleHeadlessSelection pos=$position")
|
|
700
1022
|
onSelect?.invoke(position, opt.label, opt.data)
|
|
701
1023
|
}
|
|
702
1024
|
|
|
@@ -706,9 +1028,19 @@ class PCSelectionMenuView(context: Context) : FrameLayout(context), ReactScrollV
|
|
|
706
1028
|
menu.clear()
|
|
707
1029
|
val selectedIdx = options.indexOfFirst { it.data == selectedData }
|
|
708
1030
|
options.forEachIndexed { index, opt ->
|
|
709
|
-
val
|
|
710
|
-
|
|
1031
|
+
val item = menu.add(HEADLESS_GROUP_ID, index, index, opt.label)
|
|
1032
|
+
item.isEnabled = !opt.disabled
|
|
1033
|
+
item.isChecked = index == selectedIdx
|
|
1034
|
+
// PopupMenu rows have one line, so only the icon is shown (no subtitle)
|
|
1035
|
+
if (opt.icon.isPresent) {
|
|
1036
|
+
PCMenuSupport.loadIcon(context, opt.icon) { drawable ->
|
|
1037
|
+
if (drawable != null && headlessMenu === popup) item.icon = drawable
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
711
1040
|
}
|
|
1041
|
+
// Single-choice group: the menu draws a native radio indicator on each row.
|
|
1042
|
+
menu.setGroupCheckable(HEADLESS_GROUP_ID, true, true)
|
|
1043
|
+
popup.setForceShowIcon(options.any { it.icon.isPresent })
|
|
712
1044
|
}
|
|
713
1045
|
|
|
714
1046
|
private fun suppressInlineSpinnerCallbacks(sp: Spinner) {
|
|
@@ -13,6 +13,7 @@ import com.facebook.react.uimanager.events.Event
|
|
|
13
13
|
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
14
14
|
import com.facebook.react.viewmanagers.PCSelectionMenuManagerDelegate
|
|
15
15
|
import com.facebook.react.viewmanagers.PCSelectionMenuManagerInterface
|
|
16
|
+
import com.platformcomponents.PCButtonSupport.stringOr
|
|
16
17
|
|
|
17
18
|
class PCSelectionMenuViewManager :
|
|
18
19
|
SimpleViewManager<PCSelectionMenuView>(),
|
|
@@ -49,6 +50,7 @@ class PCSelectionMenuViewManager :
|
|
|
49
50
|
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.id)
|
|
50
51
|
|
|
51
52
|
view.onSelect = { index, label, data ->
|
|
53
|
+
PCHaptics.perform(view, view.haptics)
|
|
52
54
|
dispatcher?.dispatchEvent(SelectEvent(view.id, index, label, data))
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -57,15 +59,21 @@ class PCSelectionMenuViewManager :
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
// options: array of {label,data}
|
|
62
|
+
// options: array of {label, data, subtitle, iconType, iconName, iconUri, iconScale, iconTinted}
|
|
61
63
|
override fun setOptions(view: PCSelectionMenuView, value: ReadableArray?) {
|
|
62
64
|
val out = ArrayList<PCSelectionMenuView.Option>()
|
|
63
65
|
if (value != null) {
|
|
64
66
|
for (i in 0 until value.size()) {
|
|
65
67
|
val m = value.getMap(i) ?: continue
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
out.add(
|
|
69
|
+
PCSelectionMenuView.Option(
|
|
70
|
+
label = m.stringOr("label", ""),
|
|
71
|
+
data = m.stringOr("data", ""),
|
|
72
|
+
subtitle = m.stringOr("subtitle", ""),
|
|
73
|
+
disabled = m.stringOr("disabled", "false") == "true",
|
|
74
|
+
icon = PCButtonSupport.parseIcon(m)
|
|
75
|
+
)
|
|
76
|
+
)
|
|
69
77
|
}
|
|
70
78
|
}
|
|
71
79
|
view.applyOptions(out)
|
|
@@ -92,10 +100,16 @@ class PCSelectionMenuViewManager :
|
|
|
92
100
|
view.applyVisible(value)
|
|
93
101
|
}
|
|
94
102
|
|
|
103
|
+
// "" (none added) | "none" | "selection" | "light" | "medium" | "heavy" | "success" | "warning" | "error"
|
|
104
|
+
override fun setHaptics(view: PCSelectionMenuView, value: String?) {
|
|
105
|
+
view.haptics = PCHaptics.configure(view, value)
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
override fun setAndroid(view: PCSelectionMenuView, value: ReadableMap?) {
|
|
96
109
|
val material =
|
|
97
110
|
if (value != null && value.hasKey("material") && !value.isNull("material")) value.getString("material") else null
|
|
98
111
|
view.applyAndroidMaterial(material)
|
|
112
|
+
view.applyAndroidSearchable(value?.stringOr("searchable", "false") == "true")
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
override fun setIos(view: PCSelectionMenuView, value: ReadableMap?) {
|