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
package/ios/PCButton.mm
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// PCButton.mm
|
|
2
|
+
|
|
3
|
+
#import "PCButton.h"
|
|
4
|
+
|
|
5
|
+
#import <React/RCTComponentViewFactory.h>
|
|
6
|
+
#import <React/RCTConversions.h>
|
|
7
|
+
#import <React/RCTFabricComponentsPlugins.h>
|
|
8
|
+
#import <React/RCTFont.h>
|
|
9
|
+
|
|
10
|
+
#import <react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h>
|
|
11
|
+
#import <react/renderer/components/PlatformComponentsViewSpec/EventEmitters.h>
|
|
12
|
+
#import <react/renderer/components/PlatformComponentsViewSpec/Props.h>
|
|
13
|
+
#import <react/renderer/core/LayoutPrimitives.h>
|
|
14
|
+
|
|
15
|
+
#if __has_include(<PlatformComponents/PlatformComponents-Swift.h>)
|
|
16
|
+
#import <PlatformComponents/PlatformComponents-Swift.h>
|
|
17
|
+
#else
|
|
18
|
+
#import "PlatformComponents-Swift.h"
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
#import "PCButtonComponentDescriptors-custom.h"
|
|
22
|
+
#import "PCButtonShadowNode-custom.h"
|
|
23
|
+
#import "PCButtonState-custom.h"
|
|
24
|
+
|
|
25
|
+
using namespace facebook::react;
|
|
26
|
+
|
|
27
|
+
namespace {
|
|
28
|
+
static inline NSString *NSStringFromStd(const std::string &s, NSString *fallback) {
|
|
29
|
+
return s.empty() ? fallback : [NSString stringWithUTF8String:s.c_str()];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static inline bool IconEqual(const PCButtonIconStruct &a, const PCButtonIconStruct &b) {
|
|
33
|
+
return a.iconType == b.iconType && a.iconName == b.iconName && a.iconUri == b.iconUri &&
|
|
34
|
+
a.iconScale == b.iconScale && a.iconTinted == b.iconTinted;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static inline bool LabelStyleEqual(
|
|
38
|
+
const PCButtonLabelStyleStruct &a,
|
|
39
|
+
const PCButtonLabelStyleStruct &b) {
|
|
40
|
+
return a.fontFamily == b.fontFamily && a.fontSize == b.fontSize &&
|
|
41
|
+
a.fontWeight == b.fontWeight && a.fontStyle == b.fontStyle;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// Builds the label font from RN-style font props, or nil when every field is
|
|
45
|
+
/// unset so the button keeps the configuration's font.
|
|
46
|
+
static UIFont *FontFromLabelStyle(const PCButtonLabelStyleStruct &style) {
|
|
47
|
+
if (style.fontFamily.empty() && style.fontSize <= 0 &&
|
|
48
|
+
style.fontWeight.empty() && style.fontStyle.empty()) {
|
|
49
|
+
return nil;
|
|
50
|
+
}
|
|
51
|
+
// UIButton titles default to the body text style; start there so a lone
|
|
52
|
+
// fontWeight or fontStyle doesn't change the size.
|
|
53
|
+
return [RCTFont updateFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]
|
|
54
|
+
withFamily:NSStringFromStd(style.fontFamily, nil)
|
|
55
|
+
size:style.fontSize > 0 ? @(style.fontSize) : nil
|
|
56
|
+
weight:NSStringFromStd(style.fontWeight, nil)
|
|
57
|
+
style:NSStringFromStd(style.fontStyle, nil)
|
|
58
|
+
variant:nil
|
|
59
|
+
scaleMultiplier:1.0];
|
|
60
|
+
}
|
|
61
|
+
} // namespace
|
|
62
|
+
|
|
63
|
+
@interface PCButton ()
|
|
64
|
+
|
|
65
|
+
- (void)updateMeasurements;
|
|
66
|
+
|
|
67
|
+
@end
|
|
68
|
+
|
|
69
|
+
@implementation PCButton {
|
|
70
|
+
PCButtonView *_view;
|
|
71
|
+
MeasuringPCButtonShadowNode::ConcreteState::Shared _state;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
75
|
+
return concreteComponentDescriptorProvider<MeasuringPCButtonComponentDescriptor>();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
79
|
+
if (self = [super initWithFrame:frame]) {
|
|
80
|
+
_view = [PCButtonView new];
|
|
81
|
+
self.contentView = _view;
|
|
82
|
+
|
|
83
|
+
__weak __typeof(self) weakSelf = self;
|
|
84
|
+
|
|
85
|
+
_view.onPress = ^{
|
|
86
|
+
__typeof(self) strongSelf = weakSelf;
|
|
87
|
+
if (!strongSelf) return;
|
|
88
|
+
|
|
89
|
+
auto eventEmitter =
|
|
90
|
+
std::static_pointer_cast<const PCButtonEventEmitter>(strongSelf->_eventEmitter);
|
|
91
|
+
if (!eventEmitter) return;
|
|
92
|
+
|
|
93
|
+
eventEmitter->onButtonPress({});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
_view.onNeedsRemeasure = ^{
|
|
97
|
+
__typeof(self) strongSelf = weakSelf;
|
|
98
|
+
if (!strongSelf) return;
|
|
99
|
+
[strongSelf updateMeasurements];
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return self;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
- (void)updateProps:(Props::Shared const &)props
|
|
106
|
+
oldProps:(Props::Shared const &)oldProps {
|
|
107
|
+
const auto &newProps = *std::static_pointer_cast<const PCButtonProps>(props);
|
|
108
|
+
const auto prevProps = std::static_pointer_cast<const PCButtonProps>(oldProps);
|
|
109
|
+
|
|
110
|
+
if (!prevProps || newProps.label != prevProps->label) {
|
|
111
|
+
_view.label = NSStringFromStd(newProps.label, @"");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// icon: {iconType, iconName, iconUri, iconScale, iconTinted}
|
|
115
|
+
if (!prevProps || !IconEqual(newProps.icon, prevProps->icon)) {
|
|
116
|
+
const auto &icon = newProps.icon;
|
|
117
|
+
[_view setIconWithType:NSStringFromStd(icon.iconType, @"")
|
|
118
|
+
name:NSStringFromStd(icon.iconName, @"")
|
|
119
|
+
uri:NSStringFromStd(icon.iconUri, @"")
|
|
120
|
+
scale:icon.iconScale
|
|
121
|
+
tinted:(icon.iconTinted != "false")];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!prevProps || newProps.variant != prevProps->variant) {
|
|
125
|
+
_view.variant = NSStringFromStd(newProps.variant, @"filled");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!prevProps || newProps.size != prevProps->size) {
|
|
129
|
+
_view.size = NSStringFromStd(newProps.size, @"small");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!prevProps || newProps.shape != prevProps->shape) {
|
|
133
|
+
_view.shape = NSStringFromStd(newProps.shape, @"");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!prevProps || newProps.interactivity != prevProps->interactivity) {
|
|
137
|
+
_view.interactivity = NSStringFromStd(newProps.interactivity, @"enabled");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Colors arrive as SharedColor (already processed by React Native)
|
|
141
|
+
if (!prevProps || newProps.color != prevProps->color) {
|
|
142
|
+
_view.containerColor = RCTUIColorFromSharedColor(newProps.color);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (!prevProps || newProps.foregroundColor != prevProps->foregroundColor) {
|
|
146
|
+
_view.foregroundColor = RCTUIColorFromSharedColor(newProps.foregroundColor);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// labelStyle: {fontFamily, fontSize, fontWeight, fontStyle}
|
|
150
|
+
if (!prevProps || !LabelStyleEqual(newProps.labelStyle, prevProps->labelStyle)) {
|
|
151
|
+
_view.labelFont = FontFromLabelStyle(newProps.labelStyle);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!prevProps || newProps.spokenLabel != prevProps->spokenLabel) {
|
|
155
|
+
_view.spokenLabel = NSStringFromStd(newProps.spokenLabel, @"");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// androidRippleColor / androidStrokeColor: Android only
|
|
159
|
+
|
|
160
|
+
[super updateProps:props oldProps:oldProps];
|
|
161
|
+
|
|
162
|
+
// Update measurements when props change that affect layout
|
|
163
|
+
[self updateMeasurements];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#pragma mark - State (Measuring)
|
|
167
|
+
|
|
168
|
+
- (void)updateState:(const State::Shared &)state
|
|
169
|
+
oldState:(const State::Shared &)oldState {
|
|
170
|
+
_state = std::static_pointer_cast<const MeasuringPCButtonShadowNode::ConcreteState>(state);
|
|
171
|
+
|
|
172
|
+
if (oldState == nullptr) {
|
|
173
|
+
// First time: compute initial size.
|
|
174
|
+
[self updateMeasurements];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
[super updateState:state oldState:oldState];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
- (void)updateMeasurements {
|
|
181
|
+
if (_state == nullptr)
|
|
182
|
+
return;
|
|
183
|
+
|
|
184
|
+
// The button's natural size; Yoga clamps it to the available width
|
|
185
|
+
CGSize size = [_view sizeForLayoutWithConstrainedTo:CGSizeZero];
|
|
186
|
+
|
|
187
|
+
PCButtonStateFrameSize next;
|
|
188
|
+
next.frameSize = {(Float)size.width, (Float)size.height};
|
|
189
|
+
_state->updateState(std::move(next));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@end
|
|
193
|
+
|
|
194
|
+
Class<RCTComponentViewProtocol> PCButtonCls(void) {
|
|
195
|
+
return PCButton.class;
|
|
196
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
// PCButtonGroup.mm
|
|
2
|
+
|
|
3
|
+
#import "PCButtonGroup.h"
|
|
4
|
+
|
|
5
|
+
#import <React/RCTComponentViewFactory.h>
|
|
6
|
+
#import <React/RCTConversions.h>
|
|
7
|
+
#import <React/RCTFabricComponentsPlugins.h>
|
|
8
|
+
#import <React/RCTFont.h>
|
|
9
|
+
|
|
10
|
+
#import <react/renderer/components/PlatformComponentsViewSpec/ComponentDescriptors.h>
|
|
11
|
+
#import <react/renderer/components/PlatformComponentsViewSpec/EventEmitters.h>
|
|
12
|
+
#import <react/renderer/components/PlatformComponentsViewSpec/Props.h>
|
|
13
|
+
#import <react/renderer/core/LayoutPrimitives.h>
|
|
14
|
+
|
|
15
|
+
#if __has_include(<PlatformComponents/PlatformComponents-Swift.h>)
|
|
16
|
+
#import <PlatformComponents/PlatformComponents-Swift.h>
|
|
17
|
+
#else
|
|
18
|
+
#import "PlatformComponents-Swift.h"
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
#import "PCButtonGroupComponentDescriptors-custom.h"
|
|
22
|
+
#import "PCButtonGroupShadowNode-custom.h"
|
|
23
|
+
#import "PCButtonGroupState-custom.h"
|
|
24
|
+
|
|
25
|
+
using namespace facebook::react;
|
|
26
|
+
|
|
27
|
+
namespace {
|
|
28
|
+
static inline bool ButtonsEqual(
|
|
29
|
+
const std::vector<PCButtonGroupButtonsStruct> &a,
|
|
30
|
+
const std::vector<PCButtonGroupButtonsStruct> &b) {
|
|
31
|
+
if (a.size() != b.size()) return false;
|
|
32
|
+
for (size_t i = 0; i < a.size(); i++) {
|
|
33
|
+
if (a[i].label != b[i].label) return false;
|
|
34
|
+
if (a[i].value != b[i].value) return false;
|
|
35
|
+
if (a[i].disabled != b[i].disabled) return false;
|
|
36
|
+
if (a[i].iconType != b[i].iconType) return false;
|
|
37
|
+
if (a[i].iconName != b[i].iconName) return false;
|
|
38
|
+
if (a[i].iconUri != b[i].iconUri) return false;
|
|
39
|
+
if (a[i].iconScale != b[i].iconScale) return false;
|
|
40
|
+
if (a[i].iconTinted != b[i].iconTinted) return false;
|
|
41
|
+
if (a[i].accessibilityLabel != b[i].accessibilityLabel) return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static inline NSString *NSStringFromStd(const std::string &s, NSString *fallback) {
|
|
47
|
+
return s.empty() ? fallback : [NSString stringWithUTF8String:s.c_str()];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static inline NSArray<NSString *> *NSArrayFromStd(const std::vector<std::string> &values) {
|
|
51
|
+
NSMutableArray<NSString *> *arr = [NSMutableArray arrayWithCapacity:values.size()];
|
|
52
|
+
for (const auto &value : values) {
|
|
53
|
+
[arr addObject:NSStringFromStd(value, @"")];
|
|
54
|
+
}
|
|
55
|
+
return arr;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static inline bool LabelStyleEqual(
|
|
59
|
+
const PCButtonGroupLabelStyleStruct &a,
|
|
60
|
+
const PCButtonGroupLabelStyleStruct &b) {
|
|
61
|
+
return a.fontFamily == b.fontFamily && a.fontSize == b.fontSize &&
|
|
62
|
+
a.fontWeight == b.fontWeight && a.fontStyle == b.fontStyle;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// Builds the label font from RN-style font props, or nil when every field is
|
|
66
|
+
/// unset so the buttons keep the configuration's font.
|
|
67
|
+
static UIFont *FontFromLabelStyle(const PCButtonGroupLabelStyleStruct &style) {
|
|
68
|
+
if (style.fontFamily.empty() && style.fontSize <= 0 &&
|
|
69
|
+
style.fontWeight.empty() && style.fontStyle.empty()) {
|
|
70
|
+
return nil;
|
|
71
|
+
}
|
|
72
|
+
return [RCTFont updateFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]
|
|
73
|
+
withFamily:NSStringFromStd(style.fontFamily, nil)
|
|
74
|
+
size:style.fontSize > 0 ? @(style.fontSize) : nil
|
|
75
|
+
weight:NSStringFromStd(style.fontWeight, nil)
|
|
76
|
+
style:NSStringFromStd(style.fontStyle, nil)
|
|
77
|
+
variant:nil
|
|
78
|
+
scaleMultiplier:1.0];
|
|
79
|
+
}
|
|
80
|
+
} // namespace
|
|
81
|
+
|
|
82
|
+
@interface PCButtonGroup ()
|
|
83
|
+
|
|
84
|
+
- (void)updateMeasurements;
|
|
85
|
+
|
|
86
|
+
@end
|
|
87
|
+
|
|
88
|
+
@implementation PCButtonGroup {
|
|
89
|
+
PCButtonGroupView *_view;
|
|
90
|
+
MeasuringPCButtonGroupShadowNode::ConcreteState::Shared _state;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
94
|
+
return concreteComponentDescriptorProvider<MeasuringPCButtonGroupComponentDescriptor>();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
98
|
+
if (self = [super initWithFrame:frame]) {
|
|
99
|
+
_view = [PCButtonGroupView new];
|
|
100
|
+
self.contentView = _view;
|
|
101
|
+
|
|
102
|
+
__weak __typeof(self) weakSelf = self;
|
|
103
|
+
|
|
104
|
+
_view.onPress = ^(NSInteger index, NSString *value) {
|
|
105
|
+
__typeof(self) strongSelf = weakSelf;
|
|
106
|
+
if (!strongSelf) return;
|
|
107
|
+
|
|
108
|
+
auto eventEmitter =
|
|
109
|
+
std::static_pointer_cast<const PCButtonGroupEventEmitter>(strongSelf->_eventEmitter);
|
|
110
|
+
if (!eventEmitter) return;
|
|
111
|
+
|
|
112
|
+
PCButtonGroupEventEmitter::OnButtonPress payload = {
|
|
113
|
+
.index = (int)index,
|
|
114
|
+
.value = value.UTF8String,
|
|
115
|
+
};
|
|
116
|
+
eventEmitter->onButtonPress(payload);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
_view.onSelectionChange = ^(NSArray<NSString *> *values) {
|
|
120
|
+
__typeof(self) strongSelf = weakSelf;
|
|
121
|
+
if (!strongSelf) return;
|
|
122
|
+
|
|
123
|
+
auto eventEmitter =
|
|
124
|
+
std::static_pointer_cast<const PCButtonGroupEventEmitter>(strongSelf->_eventEmitter);
|
|
125
|
+
if (!eventEmitter) return;
|
|
126
|
+
|
|
127
|
+
PCButtonGroupEventEmitter::OnGroupSelectionChange payload;
|
|
128
|
+
for (NSString *value in values) {
|
|
129
|
+
payload.values.push_back(value.UTF8String);
|
|
130
|
+
}
|
|
131
|
+
eventEmitter->onGroupSelectionChange(payload);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
_view.onNeedsRemeasure = ^{
|
|
135
|
+
__typeof(self) strongSelf = weakSelf;
|
|
136
|
+
if (!strongSelf) return;
|
|
137
|
+
[strongSelf updateMeasurements];
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return self;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
- (void)updateProps:(Props::Shared const &)props
|
|
144
|
+
oldProps:(Props::Shared const &)oldProps {
|
|
145
|
+
const auto &newProps = *std::static_pointer_cast<const PCButtonGroupProps>(props);
|
|
146
|
+
const auto prevProps = std::static_pointer_cast<const PCButtonGroupProps>(oldProps);
|
|
147
|
+
|
|
148
|
+
// buttons: [{label, value, disabled, iconType, iconName, iconUri, iconScale,
|
|
149
|
+
// iconTinted, accessibilityLabel}]
|
|
150
|
+
if (!prevProps || !ButtonsEqual(newProps.buttons, prevProps->buttons)) {
|
|
151
|
+
NSMutableArray *arr = [NSMutableArray new];
|
|
152
|
+
for (const auto &button : newProps.buttons) {
|
|
153
|
+
[arr addObject:@{
|
|
154
|
+
@"label": NSStringFromStd(button.label, @""),
|
|
155
|
+
@"value": NSStringFromStd(button.value, @""),
|
|
156
|
+
@"disabled": NSStringFromStd(button.disabled, @"enabled"),
|
|
157
|
+
@"iconType": NSStringFromStd(button.iconType, @""),
|
|
158
|
+
@"iconName": NSStringFromStd(button.iconName, @""),
|
|
159
|
+
@"iconUri": NSStringFromStd(button.iconUri, @""),
|
|
160
|
+
@"iconScale": @(button.iconScale),
|
|
161
|
+
@"iconTinted": NSStringFromStd(button.iconTinted, @"true"),
|
|
162
|
+
@"accessibilityLabel": NSStringFromStd(button.accessibilityLabel, @""),
|
|
163
|
+
}];
|
|
164
|
+
}
|
|
165
|
+
_view.buttons = arr;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!prevProps || newProps.variant != prevProps->variant) {
|
|
169
|
+
_view.variant = NSStringFromStd(newProps.variant, @"outlined");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (!prevProps || newProps.size != prevProps->size) {
|
|
173
|
+
_view.size = NSStringFromStd(newProps.size, @"small");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!prevProps || newProps.shape != prevProps->shape) {
|
|
177
|
+
_view.shape = NSStringFromStd(newProps.shape, @"");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (!prevProps || newProps.connected != prevProps->connected) {
|
|
181
|
+
_view.connected = (newProps.connected == "true");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (!prevProps || newProps.spacing != prevProps->spacing) {
|
|
185
|
+
_view.spacing = newProps.spacing;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (!prevProps || newProps.selection != prevProps->selection) {
|
|
189
|
+
_view.selection = NSStringFromStd(newProps.selection, @"none");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!prevProps || newProps.selectedValues != prevProps->selectedValues) {
|
|
193
|
+
_view.selectedValues = NSArrayFromStd(newProps.selectedValues);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (!prevProps || newProps.selectionRequired != prevProps->selectionRequired) {
|
|
197
|
+
_view.selectionRequired = (newProps.selectionRequired == "true");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (!prevProps || newProps.interactivity != prevProps->interactivity) {
|
|
201
|
+
_view.interactivity = NSStringFromStd(newProps.interactivity, @"enabled");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Colors arrive as SharedColor (already processed by React Native)
|
|
205
|
+
if (!prevProps || newProps.color != prevProps->color) {
|
|
206
|
+
_view.containerColor = RCTUIColorFromSharedColor(newProps.color);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!prevProps || newProps.foregroundColor != prevProps->foregroundColor) {
|
|
210
|
+
_view.foregroundColor = RCTUIColorFromSharedColor(newProps.foregroundColor);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// labelStyle: {fontFamily, fontSize, fontWeight, fontStyle}
|
|
214
|
+
if (!prevProps || !LabelStyleEqual(newProps.labelStyle, prevProps->labelStyle)) {
|
|
215
|
+
_view.labelFont = FontFromLabelStyle(newProps.labelStyle);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// androidRippleColor / androidStrokeColor / android: Android only
|
|
219
|
+
|
|
220
|
+
[super updateProps:props oldProps:oldProps];
|
|
221
|
+
|
|
222
|
+
// Update measurements when props change that affect layout
|
|
223
|
+
[self updateMeasurements];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
#pragma mark - State (Measuring)
|
|
227
|
+
|
|
228
|
+
- (void)updateState:(const State::Shared &)state
|
|
229
|
+
oldState:(const State::Shared &)oldState {
|
|
230
|
+
_state = std::static_pointer_cast<const MeasuringPCButtonGroupShadowNode::ConcreteState>(state);
|
|
231
|
+
|
|
232
|
+
if (oldState == nullptr) {
|
|
233
|
+
// First time: compute initial size.
|
|
234
|
+
[self updateMeasurements];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
[super updateState:state oldState:oldState];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
- (void)updateMeasurements {
|
|
241
|
+
if (_state == nullptr)
|
|
242
|
+
return;
|
|
243
|
+
|
|
244
|
+
// The group's natural size; Yoga clamps it to the available width
|
|
245
|
+
CGSize size = [_view sizeForLayoutWithConstrainedTo:CGSizeZero];
|
|
246
|
+
|
|
247
|
+
PCButtonGroupStateFrameSize next;
|
|
248
|
+
next.frameSize = {(Float)size.width, (Float)size.height};
|
|
249
|
+
_state->updateState(std::move(next));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
@end
|
|
253
|
+
|
|
254
|
+
Class<RCTComponentViewProtocol> PCButtonGroupCls(void) {
|
|
255
|
+
return PCButtonGroup.class;
|
|
256
|
+
}
|