react-native-platform-components 1.2.0 → 1.4.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/README.md +33 -31
- package/android/src/main/java/com/platformcomponents/PCButtonGroupView.kt +498 -0
- package/android/src/main/java/com/platformcomponents/PCButtonGroupViewManager.kt +191 -0
- package/android/src/main/java/com/platformcomponents/PCButtonSupport.kt +127 -0
- package/android/src/main/java/com/platformcomponents/PCButtonView.kt +345 -0
- package/android/src/main/java/com/platformcomponents/PCButtonViewManager.kt +126 -0
- package/android/src/main/java/com/platformcomponents/PCExpressive.kt +107 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarView.kt +115 -0
- package/android/src/main/java/com/platformcomponents/PCFloatingToolbarViewManager.kt +65 -0
- package/android/src/main/java/com/platformcomponents/PCNativeThemeModule.kt +3 -0
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlView.kt +13 -5
- package/android/src/main/java/com/platformcomponents/PCSegmentedControlViewManager.kt +6 -1
- package/android/src/main/java/com/platformcomponents/PCTextFieldView.kt +1018 -0
- package/android/src/main/java/com/platformcomponents/PCTextFieldViewManager.kt +248 -0
- package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +13 -6
- package/android/src/main/jni/CMakeLists.txt +13 -1
- package/android/src/main/res/values/attrs.xml +13 -0
- package/android/src/main/res/values/styles.xml +183 -0
- package/ios/PCButton.h +10 -0
- package/ios/PCButton.mm +196 -0
- package/ios/PCButtonGroup.h +10 -0
- package/ios/PCButtonGroup.mm +256 -0
- package/ios/PCButtonGroupView.swift +254 -0
- package/ios/PCButtonSupport.swift +141 -0
- package/ios/PCButtonView.swift +155 -0
- package/ios/PCFloatingToolbar.h +10 -0
- package/ios/PCFloatingToolbar.mm +76 -0
- package/ios/PCFloatingToolbarView.swift +95 -0
- package/ios/PCNativeThemeModule.mm +13 -0
- package/ios/PCSelectionMenu.swift +9 -1
- package/ios/PCTextField.h +10 -0
- package/ios/PCTextField.mm +391 -0
- package/ios/PCTextFieldView.swift +1012 -0
- package/lib/commonjs/Button.js +77 -0
- package/lib/commonjs/Button.js.map +1 -0
- package/lib/commonjs/ButtonGroup.js +99 -0
- package/lib/commonjs/ButtonGroup.js.map +1 -0
- package/lib/commonjs/ButtonGroupNativeComponent.ts +121 -0
- package/lib/commonjs/ButtonNativeComponent.ts +76 -0
- package/lib/commonjs/ContextMenuNativeComponent.ts +5 -4
- package/lib/commonjs/DatePickerNativeComponent.ts +17 -11
- package/lib/commonjs/FloatingToolbar.js +69 -0
- package/lib/commonjs/FloatingToolbar.js.map +1 -0
- package/lib/commonjs/FloatingToolbarNativeComponent.ts +31 -0
- package/lib/commonjs/LiquidGlass.js +24 -4
- package/lib/commonjs/LiquidGlass.js.map +1 -1
- package/lib/commonjs/LiquidGlassNativeComponent.ts +6 -5
- package/lib/commonjs/NativePlatformComponentsTheme.js.map +1 -1
- package/lib/commonjs/SegmentedControl.js +11 -85
- package/lib/commonjs/SegmentedControl.js.map +1 -1
- package/lib/commonjs/SegmentedControlNativeComponent.ts +15 -11
- package/lib/commonjs/SelectionMenuNativeComponent.ts +6 -5
- package/lib/commonjs/TextField.js +195 -0
- package/lib/commonjs/TextField.js.map +1 -0
- package/lib/commonjs/TextFieldNativeComponent.ts +218 -0
- package/lib/commonjs/codegenTypes.js +6 -0
- package/lib/commonjs/codegenTypes.js.map +1 -0
- package/lib/commonjs/focusRegistry.js +78 -0
- package/lib/commonjs/focusRegistry.js.map +1 -0
- package/lib/commonjs/icons.js +92 -0
- package/lib/commonjs/icons.js.map +1 -0
- package/lib/commonjs/index.js +66 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +32 -2
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/labelStyle.js +27 -0
- package/lib/commonjs/labelStyle.js.map +1 -0
- package/lib/commonjs/reactNativeInternals.d.js +2 -0
- package/lib/commonjs/reactNativeInternals.d.js.map +1 -0
- package/lib/module/Button.js +70 -0
- package/lib/module/Button.js.map +1 -0
- package/lib/module/ButtonGroup.js +92 -0
- package/lib/module/ButtonGroup.js.map +1 -0
- package/lib/module/ButtonGroupNativeComponent.ts +121 -0
- package/lib/module/ButtonNativeComponent.ts +76 -0
- package/lib/module/ContextMenuNativeComponent.ts +5 -4
- package/lib/module/DatePickerNativeComponent.ts +17 -11
- package/lib/module/FloatingToolbar.js +62 -0
- package/lib/module/FloatingToolbar.js.map +1 -0
- package/lib/module/FloatingToolbarNativeComponent.ts +31 -0
- package/lib/module/LiquidGlass.js +24 -4
- package/lib/module/LiquidGlass.js.map +1 -1
- package/lib/module/LiquidGlassNativeComponent.ts +6 -5
- package/lib/module/NativePlatformComponentsTheme.js.map +1 -1
- package/lib/module/SegmentedControl.js +12 -87
- package/lib/module/SegmentedControl.js.map +1 -1
- package/lib/module/SegmentedControlNativeComponent.ts +15 -11
- package/lib/module/SelectionMenuNativeComponent.ts +6 -5
- package/lib/module/TextField.js +189 -0
- package/lib/module/TextField.js.map +1 -0
- package/lib/module/TextFieldNativeComponent.ts +218 -0
- package/lib/module/codegenTypes.js +4 -0
- package/lib/module/codegenTypes.js.map +1 -0
- package/lib/module/focusRegistry.js +74 -0
- package/lib/module/focusRegistry.js.map +1 -0
- package/lib/module/icons.js +87 -0
- package/lib/module/icons.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +28 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/labelStyle.js +23 -0
- package/lib/module/labelStyle.js.map +1 -0
- package/lib/module/reactNativeInternals.d.js +2 -0
- package/lib/module/reactNativeInternals.d.js.map +1 -0
- package/lib/typescript/commonjs/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/Button.d.ts +76 -0
- package/lib/typescript/commonjs/src/Button.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts +102 -0
- package/lib/typescript/commonjs/src/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts +93 -0
- package/lib/typescript/commonjs/src/ButtonGroupNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts +57 -0
- package/lib/typescript/commonjs/src/ButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts +5 -4
- package/lib/typescript/commonjs/src/ContextMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts +12 -11
- package/lib/typescript/commonjs/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts +45 -0
- package/lib/typescript/commonjs/src/FloatingToolbar.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts +24 -0
- package/lib/typescript/commonjs/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/LiquidGlass.d.ts +4 -3
- package/lib/typescript/commonjs/src/LiquidGlass.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts +6 -5
- package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/NativePlatformComponentsTheme.d.ts +10 -2
- package/lib/typescript/commonjs/src/NativePlatformComponentsTheme.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts +17 -46
- package/lib/typescript/commonjs/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts +9 -6
- package/lib/typescript/commonjs/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts +6 -5
- package/lib/typescript/commonjs/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/TextField.d.ts +174 -0
- package/lib/typescript/commonjs/src/TextField.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts +162 -0
- package/lib/typescript/commonjs/src/TextFieldNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/codegenTypes.d.ts +12 -0
- package/lib/typescript/commonjs/src/codegenTypes.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/icons.d.ts +52 -0
- package/lib/typescript/commonjs/src/icons.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +6 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.web.d.ts +121 -0
- package/lib/typescript/commonjs/src/index.web.d.ts.map +1 -1
- 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/sharedTypes.d.ts +8 -3
- package/lib/typescript/commonjs/src/sharedTypes.d.ts.map +1 -1
- package/lib/typescript/module/docs/sidebars.d.ts.map +1 -1
- package/lib/typescript/module/src/Button.d.ts +76 -0
- package/lib/typescript/module/src/Button.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonGroup.d.ts +102 -0
- package/lib/typescript/module/src/ButtonGroup.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts +93 -0
- package/lib/typescript/module/src/ButtonGroupNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts +57 -0
- package/lib/typescript/module/src/ButtonNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts +5 -4
- package/lib/typescript/module/src/ContextMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts +12 -11
- package/lib/typescript/module/src/DatePickerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/FloatingToolbar.d.ts +45 -0
- package/lib/typescript/module/src/FloatingToolbar.d.ts.map +1 -0
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts +24 -0
- package/lib/typescript/module/src/FloatingToolbarNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/LiquidGlass.d.ts +4 -3
- package/lib/typescript/module/src/LiquidGlass.d.ts.map +1 -1
- package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts +6 -5
- package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/NativePlatformComponentsTheme.d.ts +10 -2
- package/lib/typescript/module/src/NativePlatformComponentsTheme.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControl.d.ts +17 -46
- package/lib/typescript/module/src/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts +9 -6
- package/lib/typescript/module/src/SegmentedControlNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts +6 -5
- package/lib/typescript/module/src/SelectionMenuNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/TextField.d.ts +174 -0
- package/lib/typescript/module/src/TextField.d.ts.map +1 -0
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts +162 -0
- package/lib/typescript/module/src/TextFieldNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/codegenTypes.d.ts +12 -0
- package/lib/typescript/module/src/codegenTypes.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/icons.d.ts +52 -0
- package/lib/typescript/module/src/icons.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +6 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/index.web.d.ts +121 -0
- package/lib/typescript/module/src/index.web.d.ts.map +1 -1
- 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/sharedTypes.d.ts +8 -3
- package/lib/typescript/module/src/sharedTypes.d.ts.map +1 -1
- package/package.json +28 -6
- package/react-native.config.js +3 -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/PCDatePickerState-custom.h +2 -2
- package/shared/PCSegmentedControlState-custom.h +2 -2
- package/shared/PCSelectionMenuState-custom.h +2 -2
- 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 +3 -0
- package/src/Button.tsx +144 -0
- package/src/ButtonGroup.tsx +233 -0
- package/src/ButtonGroupNativeComponent.ts +121 -0
- package/src/ButtonNativeComponent.ts +76 -0
- package/src/ContextMenuNativeComponent.ts +5 -4
- package/src/DatePickerNativeComponent.ts +17 -11
- package/src/FloatingToolbar.tsx +113 -0
- package/src/FloatingToolbarNativeComponent.ts +31 -0
- package/src/LiquidGlass.tsx +24 -5
- package/src/LiquidGlassNativeComponent.ts +6 -5
- package/src/NativePlatformComponentsTheme.ts +11 -2
- package/src/SegmentedControl.tsx +26 -118
- package/src/SegmentedControlNativeComponent.ts +15 -11
- package/src/SelectionMenuNativeComponent.ts +6 -5
- package/src/TextField.tsx +494 -0
- package/src/TextFieldNativeComponent.ts +218 -0
- package/src/codegenTypes.ts +40 -0
- package/src/focusRegistry.ts +89 -0
- package/src/icons.ts +116 -0
- package/src/index.tsx +6 -0
- package/src/index.web.tsx +194 -0
- package/src/labelStyle.ts +36 -0
- package/src/reactNativeInternals.d.ts +22 -0
- package/src/sharedTypes.ts +9 -3
- /package/{app.plugin.cjs → app.plugin.js} +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
package com.platformcomponents
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import com.facebook.react.uimanager.ReactStylesDiffMap
|
|
6
|
+
import com.facebook.react.uimanager.SimpleViewManager
|
|
7
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
8
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
9
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
10
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
11
|
+
import com.facebook.react.uimanager.events.Event
|
|
12
|
+
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
13
|
+
import com.facebook.react.viewmanagers.PCButtonManagerDelegate
|
|
14
|
+
import com.facebook.react.viewmanagers.PCButtonManagerInterface
|
|
15
|
+
import com.platformcomponents.PCButtonSupport.doubleOr
|
|
16
|
+
import com.platformcomponents.PCButtonSupport.stringOr
|
|
17
|
+
|
|
18
|
+
class PCButtonViewManager :
|
|
19
|
+
SimpleViewManager<PCButtonView>(),
|
|
20
|
+
PCButtonManagerInterface<PCButtonView> {
|
|
21
|
+
|
|
22
|
+
companion object {
|
|
23
|
+
private const val TAG = "PCButton"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private val delegate: ViewManagerDelegate<PCButtonView> = PCButtonManagerDelegate(this)
|
|
27
|
+
|
|
28
|
+
override fun getName(): String = "PCButton"
|
|
29
|
+
|
|
30
|
+
override fun getDelegate(): ViewManagerDelegate<PCButtonView> = delegate
|
|
31
|
+
|
|
32
|
+
override fun createViewInstance(reactContext: ThemedReactContext): PCButtonView {
|
|
33
|
+
return PCButtonView(reactContext)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Pass the StateWrapper to the view so it can update Fabric state with its
|
|
38
|
+
* natural size, and report it right away so the first layout already fits.
|
|
39
|
+
*/
|
|
40
|
+
override fun updateState(
|
|
41
|
+
view: PCButtonView,
|
|
42
|
+
props: ReactStylesDiffMap,
|
|
43
|
+
stateWrapper: StateWrapper
|
|
44
|
+
): Any? {
|
|
45
|
+
view.stateWrapper = stateWrapper
|
|
46
|
+
view.reportIntrinsicSize()
|
|
47
|
+
return null
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override fun addEventEmitters(reactContext: ThemedReactContext, view: PCButtonView) {
|
|
51
|
+
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.id)
|
|
52
|
+
|
|
53
|
+
view.onPress = {
|
|
54
|
+
dispatcher?.dispatchEvent(PressEvent(view.id))
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override fun setLabel(view: PCButtonView, value: String?) {
|
|
59
|
+
view.applyLabel(value ?: "")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// icon: {iconType, iconName, iconUri, iconScale, iconTinted}
|
|
63
|
+
override fun setIcon(view: PCButtonView, value: ReadableMap?) {
|
|
64
|
+
view.applyIcon(PCButtonSupport.parseIcon(value))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
override fun setVariant(view: PCButtonView, value: String?) {
|
|
68
|
+
view.applyVariant(value)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override fun setSize(view: PCButtonView, value: String?) {
|
|
72
|
+
view.applySize(value)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
override fun setShape(view: PCButtonView, value: String?) {
|
|
76
|
+
view.applyShape(value)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
override fun setInteractivity(view: PCButtonView, value: String?) {
|
|
80
|
+
view.applyInteractivity(value)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Colors arrive already processed by React Native (ARGB ints)
|
|
84
|
+
override fun setColor(view: PCButtonView, value: Int?) {
|
|
85
|
+
view.applyColors(value, view.foregroundColor, view.rippleColor, view.strokeColor)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override fun setForegroundColor(view: PCButtonView, value: Int?) {
|
|
89
|
+
view.applyColors(view.containerColor, value, view.rippleColor, view.strokeColor)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
override fun setAndroidRippleColor(view: PCButtonView, value: Int?) {
|
|
93
|
+
view.applyColors(view.containerColor, view.foregroundColor, value, view.strokeColor)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
override fun setAndroidStrokeColor(view: PCButtonView, value: Int?) {
|
|
97
|
+
view.applyColors(view.containerColor, view.foregroundColor, view.rippleColor, value)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// labelStyle: {fontFamily, fontSize, fontWeight, fontStyle}; empty / 0 = default
|
|
101
|
+
override fun setLabelStyle(view: PCButtonView, value: ReadableMap?) {
|
|
102
|
+
view.applyLabelStyle(
|
|
103
|
+
fontFamily = value?.stringOr("fontFamily", "") ?: "",
|
|
104
|
+
fontSize = value?.doubleOr("fontSize", 0.0)?.toFloat() ?: 0f,
|
|
105
|
+
fontWeight = value?.stringOr("fontWeight", "") ?: "",
|
|
106
|
+
fontStyle = value?.stringOr("fontStyle", "") ?: ""
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
override fun setSpokenLabel(view: PCButtonView, value: String?) {
|
|
111
|
+
view.applySpokenLabel(value ?: "")
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// "expressive" (default) | "m3"
|
|
115
|
+
override fun setAndroidMaterial(view: PCButtonView, value: String?) {
|
|
116
|
+
view.applyMaterial(value)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// --- Events ---
|
|
120
|
+
private class PressEvent(surfaceId: Int) : Event<PressEvent>(surfaceId) {
|
|
121
|
+
override fun getEventName(): String = "topButtonPress"
|
|
122
|
+
override fun dispatch(rctEventEmitter: RCTEventEmitter) {
|
|
123
|
+
rctEventEmitter.receiveEvent(viewTag, eventName, Arguments.createMap())
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
package com.platformcomponents
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.ContextThemeWrapper
|
|
5
|
+
import androidx.appcompat.R as AppCompatR
|
|
6
|
+
import com.google.android.material.R as MaterialR
|
|
7
|
+
import com.google.android.material.button.MaterialButton
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Material 3 Expressive contexts and styles for Button and ButtonGroup.
|
|
11
|
+
*
|
|
12
|
+
* The Expressive look is a set of widget styles (PCExpressiveOverlay in
|
|
13
|
+
* styles.xml) layered over the host theme, plus one of Material's size overlays,
|
|
14
|
+
* which the Expressive button styles read their padding, icon size, label style
|
|
15
|
+
* and shapes from.
|
|
16
|
+
*/
|
|
17
|
+
object PCExpressive {
|
|
18
|
+
enum class Variant { FILLED, TONAL, OUTLINED, TEXT, ELEVATED }
|
|
19
|
+
|
|
20
|
+
fun parseVariant(value: String?): Variant =
|
|
21
|
+
when (value) {
|
|
22
|
+
"tonal" -> Variant.TONAL
|
|
23
|
+
"outlined" -> Variant.OUTLINED
|
|
24
|
+
"text" -> Variant.TEXT
|
|
25
|
+
"elevated" -> Variant.ELEVATED
|
|
26
|
+
else -> Variant.FILLED
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** "xsmall" | "small" | "medium" | "large" | "xlarge" */
|
|
30
|
+
fun parseSize(value: String?): String =
|
|
31
|
+
when (value) {
|
|
32
|
+
"xsmall", "medium", "large", "xlarge" -> value
|
|
33
|
+
else -> "small"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** "round" | "square"; the spec's empty string is the Material default, round. */
|
|
37
|
+
fun parseShape(value: String?): String = if (value == "square") "square" else "round"
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The theme overlay choosing the buttons' size and shape (PCSize.* in
|
|
41
|
+
* styles.xml): it sets the size overlay attributes the library's button
|
|
42
|
+
* styles read, for text buttons and for icon-only buttons, which use
|
|
43
|
+
* Material's square icon button sizes.
|
|
44
|
+
*/
|
|
45
|
+
fun sizeOverlay(size: String, shape: String): Int {
|
|
46
|
+
val square = shape == "square"
|
|
47
|
+
return when (size) {
|
|
48
|
+
"xsmall" -> if (square) R.style.PCSize_Xsmall_Square else R.style.PCSize_Xsmall
|
|
49
|
+
"medium" -> if (square) R.style.PCSize_Medium_Square else R.style.PCSize_Medium
|
|
50
|
+
"large" -> if (square) R.style.PCSize_Large_Square else R.style.PCSize_Large
|
|
51
|
+
"xlarge" -> if (square) R.style.PCSize_Xlarge_Square else R.style.PCSize_Xlarge
|
|
52
|
+
else -> if (square) R.style.PCSize_Small_Square else R.style.PCSize_Small
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The theme attribute naming the widget style for a variant. */
|
|
57
|
+
fun styleAttr(variant: Variant, iconOnly: Boolean): Int =
|
|
58
|
+
if (iconOnly) {
|
|
59
|
+
when (variant) {
|
|
60
|
+
Variant.FILLED -> MaterialR.attr.materialIconButtonFilledStyle
|
|
61
|
+
Variant.TONAL -> MaterialR.attr.materialIconButtonFilledTonalStyle
|
|
62
|
+
Variant.OUTLINED -> MaterialR.attr.materialIconButtonOutlinedStyle
|
|
63
|
+
Variant.TEXT, Variant.ELEVATED -> MaterialR.attr.materialIconButtonStyle
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
when (variant) {
|
|
67
|
+
Variant.FILLED -> MaterialR.attr.materialButtonStyle
|
|
68
|
+
Variant.TONAL -> MaterialR.attr.materialButtonTonalStyle
|
|
69
|
+
Variant.OUTLINED -> MaterialR.attr.materialButtonOutlinedStyle
|
|
70
|
+
Variant.TEXT -> AppCompatR.attr.borderlessButtonStyle
|
|
71
|
+
Variant.ELEVATED -> MaterialR.attr.materialButtonElevatedStyle
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** "expressive" (default) | "m3" */
|
|
76
|
+
fun parseExpressive(value: String?): Boolean = value != "m3"
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Creates a button. [base] is a Material 3 context (see
|
|
80
|
+
* PCThemeSupport.materialContext); [toolbarOverlay] is the enclosing
|
|
81
|
+
* FloatingToolbar's button overlay, or 0 outside a toolbar.
|
|
82
|
+
*
|
|
83
|
+
* With [expressive] the Material 3 Expressive styles apply, sized by the
|
|
84
|
+
* size overlay; otherwise the theme's classic Material 3 button styles,
|
|
85
|
+
* which have one size and shape. The toolbar overlay replaces the filled,
|
|
86
|
+
* text and standard icon button styles with the toolbar's, as it does for
|
|
87
|
+
* XML children of a FloatingToolbarLayout; the toolbar itself is an
|
|
88
|
+
* Expressive component, so its buttons always are.
|
|
89
|
+
*/
|
|
90
|
+
fun createButton(
|
|
91
|
+
base: Context,
|
|
92
|
+
variant: Variant,
|
|
93
|
+
size: String,
|
|
94
|
+
shape: String,
|
|
95
|
+
iconOnly: Boolean,
|
|
96
|
+
toolbarOverlay: Int,
|
|
97
|
+
expressive: Boolean = true
|
|
98
|
+
): MaterialButton {
|
|
99
|
+
if (!expressive && toolbarOverlay == 0) {
|
|
100
|
+
return MaterialButton(base, null, styleAttr(variant, iconOnly))
|
|
101
|
+
}
|
|
102
|
+
val overlaid = ContextThemeWrapper(base, R.style.PCExpressiveOverlay)
|
|
103
|
+
val themed = if (toolbarOverlay != 0) ContextThemeWrapper(overlaid, toolbarOverlay) else overlaid
|
|
104
|
+
val sized = ContextThemeWrapper(themed, sizeOverlay(size, shape))
|
|
105
|
+
return MaterialButton(sized, null, styleAttr(variant, iconOnly))
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
package com.platformcomponents
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.res.ColorStateList
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import androidx.core.content.res.ResourcesCompat
|
|
7
|
+
import com.google.android.material.R as MaterialR
|
|
8
|
+
import com.google.android.material.color.MaterialColors
|
|
9
|
+
import com.google.android.material.floatingtoolbar.FloatingToolbarLayout
|
|
10
|
+
import com.google.android.material.shape.MaterialShapeDrawable
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A Material 3 floating toolbar. The Material container (shape, elevation,
|
|
14
|
+
* color) hosts React children, which Fabric lays out itself.
|
|
15
|
+
*/
|
|
16
|
+
class PCFloatingToolbarView(context: Context) :
|
|
17
|
+
FloatingToolbarLayout(
|
|
18
|
+
// Material widgets need a Material theme; fall back to Material 3 defaults instead of crashing.
|
|
19
|
+
PCThemeSupport.materialContext(context, "FloatingToolbar"),
|
|
20
|
+
null,
|
|
21
|
+
0,
|
|
22
|
+
R.style.PCFloatingToolbar
|
|
23
|
+
) {
|
|
24
|
+
|
|
25
|
+
companion object {
|
|
26
|
+
private const val TAG = "PCFloatingToolbar"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// --- Props ---
|
|
30
|
+
var variant: String = "standard" // "standard" | "vibrant"
|
|
31
|
+
var color: Int? = null
|
|
32
|
+
|
|
33
|
+
/** The button overlay for Buttons inside this toolbar (see PCButtonView). */
|
|
34
|
+
val buttonOverlay: Int
|
|
35
|
+
get() = if (variant == "vibrant") R.style.PCToolbarOverlay_Vibrant else R.style.PCToolbarOverlay
|
|
36
|
+
|
|
37
|
+
// --- Native theme ---
|
|
38
|
+
private val nativeThemeListener = PCNativeTheme.Listener {
|
|
39
|
+
ResourcesCompat.clearCachesForTheme(context.theme)
|
|
40
|
+
applyColors()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
init {
|
|
44
|
+
clipChildren = false
|
|
45
|
+
clipToPadding = false
|
|
46
|
+
applyColors()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ---- Public apply* (called by manager) ----
|
|
50
|
+
|
|
51
|
+
fun applyVariant(value: String?) {
|
|
52
|
+
val parsed = if (value == "vibrant") "vibrant" else "standard"
|
|
53
|
+
if (variant == parsed) return
|
|
54
|
+
variant = parsed
|
|
55
|
+
applyColors()
|
|
56
|
+
// Buttons inside take the toolbar's button styles
|
|
57
|
+
for (i in 0 until childCount) {
|
|
58
|
+
(getChildAt(i) as? PCButtonView)?.refreshToolbarStyle()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fun applyColor(value: Int?) {
|
|
63
|
+
if (color == value) return
|
|
64
|
+
color = value
|
|
65
|
+
applyColors()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A `backgroundColor` style would replace the Material shape; route it into
|
|
70
|
+
* the color instead. React Native resets it with transparent.
|
|
71
|
+
*/
|
|
72
|
+
override fun setBackgroundColor(color: Int) {
|
|
73
|
+
applyColor(if (color == Color.TRANSPARENT) null else color)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private fun applyColors() {
|
|
77
|
+
val resolved = color ?: MaterialColors.getColor(
|
|
78
|
+
this,
|
|
79
|
+
if (variant == "vibrant") MaterialR.attr.colorPrimaryContainer else MaterialR.attr.colorSurfaceContainer,
|
|
80
|
+
Color.TRANSPARENT
|
|
81
|
+
)
|
|
82
|
+
val shape = background as? MaterialShapeDrawable
|
|
83
|
+
if (shape != null) {
|
|
84
|
+
shape.fillColor = ColorStateList.valueOf(resolved)
|
|
85
|
+
} else {
|
|
86
|
+
backgroundTintList = ColorStateList.valueOf(resolved)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
override fun onAttachedToWindow() {
|
|
91
|
+
super.onAttachedToWindow()
|
|
92
|
+
PCNativeTheme.addListener(nativeThemeListener)
|
|
93
|
+
PCNativeTheme.attach(context)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
override fun onDetachedFromWindow() {
|
|
97
|
+
PCNativeTheme.removeListener(nativeThemeListener)
|
|
98
|
+
super.onDetachedFromWindow()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ---- Layout ----
|
|
102
|
+
// Fabric sizes this view and positions its children; FrameLayout must not
|
|
103
|
+
// re-measure or re-position them against its own padding and gravity.
|
|
104
|
+
|
|
105
|
+
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
|
106
|
+
setMeasuredDimension(
|
|
107
|
+
MeasureSpec.getSize(widthMeasureSpec),
|
|
108
|
+
MeasureSpec.getSize(heightMeasureSpec)
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
|
113
|
+
// No-op: Fabric lays out the children
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package com.platformcomponents
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
7
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
8
|
+
import com.facebook.react.viewmanagers.PCFloatingToolbarManagerDelegate
|
|
9
|
+
import com.facebook.react.viewmanagers.PCFloatingToolbarManagerInterface
|
|
10
|
+
import com.platformcomponents.PCButtonSupport.stringOr
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Android ViewManager for FloatingToolbar. Uses ViewGroupManager since the
|
|
14
|
+
* toolbar hosts React children.
|
|
15
|
+
*/
|
|
16
|
+
class PCFloatingToolbarViewManager :
|
|
17
|
+
ViewGroupManager<PCFloatingToolbarView>(),
|
|
18
|
+
PCFloatingToolbarManagerInterface<PCFloatingToolbarView> {
|
|
19
|
+
|
|
20
|
+
companion object {
|
|
21
|
+
private const val TAG = "PCFloatingToolbar"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private val delegate: ViewManagerDelegate<PCFloatingToolbarView> =
|
|
25
|
+
PCFloatingToolbarManagerDelegate(this)
|
|
26
|
+
|
|
27
|
+
override fun getName(): String = "PCFloatingToolbar"
|
|
28
|
+
|
|
29
|
+
override fun getDelegate(): ViewManagerDelegate<PCFloatingToolbarView> = delegate
|
|
30
|
+
|
|
31
|
+
override fun createViewInstance(reactContext: ThemedReactContext): PCFloatingToolbarView {
|
|
32
|
+
return PCFloatingToolbarView(reactContext)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Colors arrive already processed by React Native (ARGB ints)
|
|
36
|
+
override fun setColor(view: PCFloatingToolbarView, value: Int?) {
|
|
37
|
+
view.applyColor(value)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override fun setIos(view: PCFloatingToolbarView, value: ReadableMap?) {
|
|
41
|
+
// iOS props are ignored on Android
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// android: {variant}
|
|
45
|
+
override fun setAndroid(view: PCFloatingToolbarView, value: ReadableMap?) {
|
|
46
|
+
view.applyVariant(value?.stringOr("variant", "standard"))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// --- ViewGroupManager child management ---
|
|
50
|
+
override fun addView(parent: PCFloatingToolbarView, child: View, index: Int) {
|
|
51
|
+
parent.addView(child, index)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
override fun removeViewAt(parent: PCFloatingToolbarView, index: Int) {
|
|
55
|
+
parent.removeViewAt(index)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override fun getChildCount(parent: PCFloatingToolbarView): Int {
|
|
59
|
+
return parent.childCount
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
override fun getChildAt(parent: PCFloatingToolbarView, index: Int): View? {
|
|
63
|
+
return parent.getChildAt(index)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -35,6 +35,9 @@ class PCNativeThemeModule(reactContext: ReactApplicationContext) :
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/** Liquid Glass is an iOS effect; Android renders the fallback View. */
|
|
39
|
+
override fun isLiquidGlassSupported(): Boolean = false
|
|
40
|
+
|
|
38
41
|
companion object {
|
|
39
42
|
const val NAME = "PlatformComponentsTheme"
|
|
40
43
|
private const val TAG = "PlatformComponents"
|
|
@@ -6,6 +6,7 @@ import android.graphics.Color
|
|
|
6
6
|
import android.graphics.drawable.BitmapDrawable
|
|
7
7
|
import android.text.TextUtils
|
|
8
8
|
import android.util.TypedValue
|
|
9
|
+
import android.view.ContextThemeWrapper
|
|
9
10
|
import android.view.View
|
|
10
11
|
import android.widget.FrameLayout
|
|
11
12
|
import android.widget.LinearLayout
|
|
@@ -66,6 +67,8 @@ class PCSegmentedControlView(context: Context) :
|
|
|
66
67
|
var labelVisibility: String = "auto" // "auto" | "labeled" | "unlabeled"
|
|
67
68
|
// Matches iOS, where a UISegmentedControl selection cannot be cleared by tapping.
|
|
68
69
|
var selectionRequired: Boolean = true
|
|
70
|
+
// android.material: "expressive" (the Material 3 Expressive connected buttons) | "m3"
|
|
71
|
+
var expressive: Boolean = true
|
|
69
72
|
|
|
70
73
|
// --- Styling (null / empty = Material theme default) ---
|
|
71
74
|
var selectedSegmentColor: Int? = null
|
|
@@ -140,9 +143,10 @@ class PCSegmentedControlView(context: Context) :
|
|
|
140
143
|
rebuildUI()
|
|
141
144
|
}
|
|
142
145
|
|
|
143
|
-
fun applyAndroidProps(required: Boolean) {
|
|
144
|
-
if (selectionRequired != required) {
|
|
146
|
+
fun applyAndroidProps(required: Boolean, expressiveStyle: Boolean) {
|
|
147
|
+
if (selectionRequired != required || expressive != expressiveStyle) {
|
|
145
148
|
selectionRequired = required
|
|
149
|
+
expressive = expressiveStyle
|
|
146
150
|
rebuildUI()
|
|
147
151
|
}
|
|
148
152
|
}
|
|
@@ -224,7 +228,11 @@ class PCSegmentedControlView(context: Context) :
|
|
|
224
228
|
val generation = rebuildGeneration
|
|
225
229
|
|
|
226
230
|
// Material widgets need a Material theme; fall back to Material 3 defaults instead of crashing.
|
|
227
|
-
val
|
|
231
|
+
val materialContext = PCThemeSupport.materialContext(context, "SegmentedControl")
|
|
232
|
+
// Expressive: the connected button group styles (2dp gaps, small inner
|
|
233
|
+
// corners, the selected segment a pill) in place of the classic segmented buttons.
|
|
234
|
+
val themedContext =
|
|
235
|
+
if (expressive) ContextThemeWrapper(materialContext, R.style.PCExpressiveOverlay) else materialContext
|
|
228
236
|
val group = MaterialButtonToggleGroup(themedContext).apply {
|
|
229
237
|
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
|
|
230
238
|
isSingleSelection = true
|
|
@@ -319,13 +327,13 @@ class PCSegmentedControlView(context: Context) :
|
|
|
319
327
|
|
|
320
328
|
when (segment.iconType) {
|
|
321
329
|
"drawable" -> {
|
|
322
|
-
button.icon = ResourceDrawableIdHelper.getResourceDrawable(context, segment.iconName)
|
|
330
|
+
button.icon = ResourceDrawableIdHelper.instance.getResourceDrawable(context, segment.iconName)
|
|
323
331
|
}
|
|
324
332
|
"image" -> {
|
|
325
333
|
val uri = segment.iconUri
|
|
326
334
|
val isResourceName = !uri.contains(':')
|
|
327
335
|
if (isResourceName) {
|
|
328
|
-
button.icon = ResourceDrawableIdHelper.getResourceDrawable(context, uri)
|
|
336
|
+
button.icon = ResourceDrawableIdHelper.instance.getResourceDrawable(context, uri)
|
|
329
337
|
} else {
|
|
330
338
|
PCImageLoader.load(context, uri, segment.iconScale) { bitmap ->
|
|
331
339
|
if (bitmap == null || generation != rebuildGeneration) return@load
|
|
@@ -146,7 +146,12 @@ class PCSegmentedControlViewManager :
|
|
|
146
146
|
} else {
|
|
147
147
|
true
|
|
148
148
|
}
|
|
149
|
-
|
|
149
|
+
// Spec sentinel: "expressive" (default) | "m3"
|
|
150
|
+
val expressive = !(
|
|
151
|
+
value != null && value.hasKey("material") && !value.isNull("material") &&
|
|
152
|
+
value.getString("material") == "m3"
|
|
153
|
+
)
|
|
154
|
+
view.applyAndroidProps(selectionRequired, expressive)
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
override fun setIos(view: PCSegmentedControlView, value: ReadableMap?) {
|