Skip to content

Commit e6587a4

Browse files
committed
feat: add new impl for header and toolbar items
1 parent 9bfc35c commit e6587a4

26 files changed

+3124
-0
lines changed

ios/bar/BarMenuContainer.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#import <Foundation/Foundation.h>
2+
3+
NS_ASSUME_NONNULL_BEGIN
4+
5+
@protocol BarMenuContainer <NSObject>
6+
- (void)updateMenu;
7+
- (void)menuItemSelected:(NSString *)identifier;
8+
- (BOOL)hasSelectedItem;
9+
- (NSArray<NSString *> *)selectedItemIDs;
10+
@end
11+
12+
NS_ASSUME_NONNULL_END

ios/bar/BarPropHelpers.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#import <React/RCTConversions.h>
2+
3+
#include <string>
4+
#include <vector>
5+
6+
static inline NSString * _Nullable ToolbarNSStringFromStringProp(const std::string &value)
7+
{
8+
if (value.empty()) {
9+
return nil;
10+
}
11+
12+
return RCTNSStringFromString(value);
13+
}
14+
15+
static inline NSArray<NSString *> * _Nonnull ToolbarNSStringArrayFromStringArrayProp(
16+
const std::vector<std::string> &value
17+
)
18+
{
19+
if (value.empty()) {
20+
return @[];
21+
}
22+
23+
NSMutableArray<NSString *> *result = [NSMutableArray arrayWithCapacity:value.size()];
24+
for (const auto &item : value) {
25+
if (!item.empty()) {
26+
[result addObject:RCTNSStringFromString(item)];
27+
}
28+
}
29+
30+
return result;
31+
}
32+
33+
static inline std::vector<std::string> ToolbarStringVectorFromNSStringArray(NSArray<NSString *> * _Nonnull value)
34+
{
35+
std::vector<std::string> result;
36+
result.reserve(value.count);
37+
38+
for (NSString *item in value) {
39+
if (item.length == 0) {
40+
continue;
41+
}
42+
result.emplace_back(item.UTF8String);
43+
}
44+
45+
return result;
46+
}
47+
48+
#define APPLY_STRING_PROP(target, oldProps, newProps, prop) \
49+
if (oldProps.prop != newProps.prop) { \
50+
target.prop = ToolbarNSStringFromStringProp(newProps.prop); \
51+
}
52+
53+
#define APPLY_STRING_ARRAY_PROP(target, oldProps, newProps, prop) \
54+
if (oldProps.prop != newProps.prop) { \
55+
target.prop = ToolbarNSStringArrayFromStringArrayProp(newProps.prop); \
56+
}
57+
58+
#define APPLY_BOOL_PROP(target, oldProps, newProps, prop) \
59+
if (oldProps.prop != newProps.prop) { \
60+
target.prop = newProps.prop; \
61+
}
62+
63+
// Codegen non-optional doubles default to 0, so we use negative as a sentinel for "unset".
64+
#define APPLY_OPTIONAL_DOUBLE_PROP(target, oldProps, newProps, prop) \
65+
if (oldProps.prop != newProps.prop) { \
66+
double value = newProps.prop; \
67+
target.prop = value >= 0 ? @(value) : nil; \
68+
}
69+
70+
#define APPLY_COLOR_PROP(target, oldProps, newProps, prop) \
71+
if (oldProps.prop != newProps.prop) { \
72+
target.prop = RCTUIColorFromSharedColor(newProps.prop); \
73+
}
74+
75+
#define APPLY_NUMBER_PROP(target, oldProps, newProps, prop) \
76+
if (oldProps.prop != newProps.prop) { \
77+
target.prop = @(newProps.prop); \
78+
}

ios/bar/RNSBarItemView.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#import <React/RCTViewComponentView.h>
2+
#import <UIKit/UIKit.h>
3+
4+
@class RNSBarView;
5+
6+
NS_ASSUME_NONNULL_BEGIN
7+
8+
@interface RNSBarItemView : RCTViewComponentView
9+
10+
@property (nonatomic, weak, nullable) RNSBarView *barParent;
11+
@property (nonatomic, copy, nullable) NSString *title;
12+
@property (nonatomic, copy, nullable) NSString *icon;
13+
@property (nonatomic, copy, nullable) NSString *placement;
14+
@property (nonatomic, copy, nullable) NSString *variant;
15+
@property (nonatomic, strong, nullable) UIColor *tintColor;
16+
@property (nonatomic, strong, nullable) NSNumber *width;
17+
@property (nonatomic, assign) BOOL disabled;
18+
@property (nonatomic, assign) BOOL selected;
19+
@property (nonatomic, copy, nullable) NSString *identifier;
20+
@property (nonatomic, assign) BOOL hidesSharedBackground;
21+
@property (nonatomic, assign) BOOL hasSharesBackground;
22+
@property (nonatomic, assign) BOOL sharesBackground;
23+
@property (nonatomic, assign) BOOL hasBadge;
24+
@property (nonatomic, strong, nullable) NSNumber *badgeCount;
25+
@property (nonatomic, copy, nullable) NSString *badgeValue;
26+
@property (nonatomic, strong, nullable) UIColor *badgeForegroundColor;
27+
@property (nonatomic, strong, nullable) UIColor *badgeBackgroundColor;
28+
@property (nonatomic, copy, nullable) NSString *badgeFontFamily;
29+
@property (nonatomic, copy, nullable) NSString *badgeFontWeight;
30+
@property (nonatomic, strong, nullable) NSNumber *badgeFontSize;
31+
@property (nonatomic, copy, nullable) NSString *titleFontFamily;
32+
@property (nonatomic, copy, nullable) NSString *titleFontWeight;
33+
@property (nonatomic, strong, nullable) NSNumber *titleFontSize;
34+
@property (nonatomic, strong, nullable) UIColor *titleColor;
35+
@property (nonatomic, copy, nullable) NSString *testID;
36+
37+
- (void)emitPress;
38+
39+
@end
40+
41+
NS_ASSUME_NONNULL_END

ios/bar/RNSBarItemView.mm

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#import "RNSBarItemView.h"
2+
3+
#import <React/RCTConversions.h>
4+
5+
#import <react/renderer/components/RNSBarViewSpec/ComponentDescriptors.h>
6+
#import <react/renderer/components/RNSBarViewSpec/EventEmitters.h>
7+
#import <react/renderer/components/RNSBarViewSpec/Props.h>
8+
#import <react/renderer/components/RNSBarViewSpec/RCTComponentViewHelpers.h>
9+
10+
#import "BarPropHelpers.h"
11+
#import "RNSBarView.h"
12+
13+
using namespace facebook::react;
14+
15+
@interface RNSBarView (BarInternal)
16+
- (void)updateBarItems;
17+
- (void)updateBarItem:(RNSBarItemView *)itemView;
18+
@end
19+
20+
@implementation RNSBarItemView
21+
22+
+ (ComponentDescriptorProvider)componentDescriptorProvider
23+
{
24+
return concreteComponentDescriptorProvider<RNSBarItemComponentDescriptor>();
25+
}
26+
27+
- (instancetype)initWithFrame:(CGRect)frame
28+
{
29+
if (self = [super initWithFrame:frame]) {
30+
static const auto defaultProps = std::make_shared<const RNSBarItemProps>();
31+
_props = defaultProps;
32+
33+
self.hidden = YES;
34+
self.userInteractionEnabled = NO;
35+
}
36+
37+
return self;
38+
}
39+
40+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
41+
{
42+
const auto &oldItemProps = *std::static_pointer_cast<RNSBarItemProps const>(_props);
43+
const auto &newItemProps = *std::static_pointer_cast<RNSBarItemProps const>(props);
44+
45+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, title);
46+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, icon);
47+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, placement);
48+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, variant);
49+
50+
APPLY_COLOR_PROP(self, oldItemProps, newItemProps, tintColor);
51+
52+
APPLY_OPTIONAL_DOUBLE_PROP(self, oldItemProps, newItemProps, width);
53+
APPLY_BOOL_PROP(self, oldItemProps, newItemProps, disabled);
54+
APPLY_BOOL_PROP(self, oldItemProps, newItemProps, selected);
55+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, accessibilityLabel);
56+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, accessibilityHint);
57+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, testID);
58+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, titleFontFamily);
59+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, titleFontWeight);
60+
APPLY_OPTIONAL_DOUBLE_PROP(self, oldItemProps, newItemProps, titleFontSize);
61+
62+
APPLY_COLOR_PROP(self, oldItemProps, newItemProps, titleColor);
63+
64+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, identifier);
65+
APPLY_BOOL_PROP(self, oldItemProps, newItemProps, hidesSharedBackground);
66+
APPLY_BOOL_PROP(self, oldItemProps, newItemProps, sharesBackground);
67+
APPLY_BOOL_PROP(self, oldItemProps, newItemProps, hasSharesBackground);
68+
APPLY_BOOL_PROP(self, oldItemProps, newItemProps, hasBadge);
69+
70+
APPLY_NUMBER_PROP(self, oldItemProps, newItemProps, badgeCount);
71+
72+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, badgeValue);
73+
74+
APPLY_COLOR_PROP(self, oldItemProps, newItemProps, badgeForegroundColor);
75+
APPLY_COLOR_PROP(self, oldItemProps, newItemProps, badgeBackgroundColor);
76+
77+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, badgeFontFamily);
78+
APPLY_STRING_PROP(self, oldItemProps, newItemProps, badgeFontWeight);
79+
APPLY_OPTIONAL_DOUBLE_PROP(self, oldItemProps, newItemProps, badgeFontSize);
80+
81+
[super updateProps:props oldProps:oldProps];
82+
83+
if (self.barParent != nil) {
84+
[self.barParent updateBarItem:self];
85+
}
86+
}
87+
88+
- (void)emitPress
89+
{
90+
if (self.disabled) {
91+
return;
92+
}
93+
94+
if (auto eventEmitter = std::static_pointer_cast<RNSBarItemEventEmitter const>(_eventEmitter)) {
95+
eventEmitter->onItemPress({});
96+
}
97+
}
98+
99+
@end

ios/bar/RNSBarMenuActionView.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#import <React/RCTViewComponentView.h>
2+
#import <UIKit/UIKit.h>
3+
4+
#import "BarMenuContainer.h"
5+
6+
NS_ASSUME_NONNULL_BEGIN
7+
8+
@interface RNSBarMenuActionView : RCTViewComponentView
9+
10+
@property (nonatomic, weak, nullable) id<BarMenuContainer> menuParent;
11+
@property (nonatomic, copy, nullable) NSString *identifier;
12+
@property (nonatomic, copy, nullable) NSString *title;
13+
@property (nonatomic, copy, nullable) NSString *subtitle;
14+
@property (nonatomic, copy, nullable) NSString *icon;
15+
@property (nonatomic, assign) BOOL disabled;
16+
@property (nonatomic, assign) BOOL destructive;
17+
@property (nonatomic, assign) BOOL keepsMenuPresented;
18+
@property (nonatomic, copy, nullable) NSString *discoverabilityLabel;
19+
@property (nonatomic, assign) UIMenuElementState state;
20+
21+
- (void)emitPress;
22+
- (UIAction *)uiAction;
23+
- (void)applySelectionState:(UIMenuElementState)state;
24+
- (void)clearSelectionState;
25+
- (UIMenuElementState)effectiveState;
26+
27+
@end
28+
29+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)