not-react-native-macos 0.87.1-rc.2 → 0.87.1-rc.4
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/Libraries/Components/View/ViewPropTypes.js +58 -0
- package/Libraries/NativeComponent/BaseViewConfig.macos.js +66 -11
- package/Libraries/NativeComponent/ViewConfigIgnore.js +5 -1
- package/Libraries/StyleSheet/PlatformColorValueTypes.macos.js +147 -10
- package/Libraries/StyleSheet/PlatformColorValueTypesMacOS.js +34 -0
- package/Libraries/StyleSheet/PlatformColorValueTypesMacOS.macos.js +55 -0
- package/Libraries/Utilities/Platform.macos.js +78 -11
- package/React/Base/RCTConvert.mm +49 -0
- package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +150 -0
- package/ReactCommon/React-Fabric.podspec +9 -0
- package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h +16 -0
- package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +39 -0
- package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h +39 -0
- package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h +59 -0
- package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp +113 -0
- package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h +66 -0
- package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +37 -0
- package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h +6 -0
- package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.mm +31 -0
- package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.mm +34 -0
- package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/RCTPlatformColorUtils.mm +23 -0
- package/index.js +10 -0
- package/macos/UIKitCompat/UIKit/UIColor.m +7 -1
- package/package.json +1 -1
|
@@ -55,6 +55,13 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
55
55
|
NSMutableSet<NSString *> *_accessibilityOrderNativeIDs;
|
|
56
56
|
RCTSwiftUIContainerViewWrapper *_swiftUIWrapper;
|
|
57
57
|
BOOL _focusable;
|
|
58
|
+
#if TARGET_OS_OSX // [macOS
|
|
59
|
+
// AppKit reads these rather than being told them, so they are answered from
|
|
60
|
+
// stored values by the overrides further down.
|
|
61
|
+
BOOL _allowsVibrancy;
|
|
62
|
+
BOOL _mouseDownCanMoveWindow;
|
|
63
|
+
NSTrackingArea *_mouseTrackingArea;
|
|
64
|
+
#endif // macOS]
|
|
58
65
|
}
|
|
59
66
|
|
|
60
67
|
#ifdef RCT_DYNAMIC_FRAMEWORKS
|
|
@@ -69,6 +76,10 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
|
|
69
76
|
if (self = [super initWithFrame:frame]) {
|
|
70
77
|
_props = ViewShadowNode::defaultSharedProps();
|
|
71
78
|
_reactSubviews = [NSMutableArray new];
|
|
79
|
+
#if TARGET_OS_OSX // [macOS] mirror HostPlatformViewProps' defaults
|
|
80
|
+
_mouseDownCanMoveWindow = YES;
|
|
81
|
+
_allowsVibrancy = NO;
|
|
82
|
+
#endif // macOS]
|
|
72
83
|
#if !TARGET_OS_TV
|
|
73
84
|
self.multipleTouchEnabled = YES;
|
|
74
85
|
#endif
|
|
@@ -608,9 +619,148 @@ static BOOL RCTLayerTransformCollapsesAxis(CALayer *layer)
|
|
|
608
619
|
|
|
609
620
|
_needsInvalidateLayer = _needsInvalidateLayer || needsInvalidateLayer;
|
|
610
621
|
|
|
622
|
+
#if TARGET_OS_OSX // [macOS
|
|
623
|
+
[self _updateMacOSProps:oldViewProps newProps:newViewProps];
|
|
624
|
+
#endif // macOS]
|
|
625
|
+
|
|
611
626
|
_props = std::static_pointer_cast<const ViewProps>(props);
|
|
612
627
|
}
|
|
613
628
|
|
|
629
|
+
#if TARGET_OS_OSX // [macOS
|
|
630
|
+
/**
|
|
631
|
+
* The props AppKit has and UIKit does not. They are declared in
|
|
632
|
+
* HostPlatformViewProps, so `ViewProps` already carries them on this platform.
|
|
633
|
+
*/
|
|
634
|
+
- (void)_updateMacOSProps:(const ViewProps &)oldViewProps newProps:(const ViewProps &)newViewProps
|
|
635
|
+
{
|
|
636
|
+
if (oldViewProps.tooltip != newViewProps.tooltip) {
|
|
637
|
+
self.toolTip = newViewProps.tooltip.has_value() ? RCTNSStringFromString(*newViewProps.tooltip) : nil;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (oldViewProps.acceptsFirstMouse != newViewProps.acceptsFirstMouse) {
|
|
641
|
+
self.acceptsFirstMouse = newViewProps.acceptsFirstMouse;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (oldViewProps.mouseDownCanMoveWindow != newViewProps.mouseDownCanMoveWindow) {
|
|
645
|
+
_mouseDownCanMoveWindow = newViewProps.mouseDownCanMoveWindow;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
if (oldViewProps.enableFocusRing != newViewProps.enableFocusRing) {
|
|
649
|
+
self.enableFocusRing = newViewProps.enableFocusRing;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// -allowsVibrancy and -canBecomeKeyView are read by AppKit rather than set,
|
|
653
|
+
// so the values are stored and the overrides below answer from them.
|
|
654
|
+
if (oldViewProps.allowsVibrancy != newViewProps.allowsVibrancy) {
|
|
655
|
+
_allowsVibrancy = newViewProps.allowsVibrancy;
|
|
656
|
+
self.needsDisplay = YES;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if (oldViewProps.focusable != newViewProps.focusable) {
|
|
660
|
+
_focusable = newViewProps.focusable;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
if (oldViewProps.hostPlatformEvents != newViewProps.hostPlatformEvents) {
|
|
664
|
+
[self _updateMouseTracking:newViewProps.hostPlatformEvents.wantsMouseTracking()];
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* A view only tracks the mouse while something is listening. Tracking every
|
|
670
|
+
* view would cost a dispatch per view per mouse move.
|
|
671
|
+
*/
|
|
672
|
+
- (void)_updateMouseTracking:(BOOL)wanted
|
|
673
|
+
{
|
|
674
|
+
if (wanted == (_mouseTrackingArea != nil)) {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
if (!wanted) {
|
|
679
|
+
[self removeTrackingArea:_mouseTrackingArea];
|
|
680
|
+
_mouseTrackingArea = nil;
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
_mouseTrackingArea = [[NSTrackingArea alloc]
|
|
685
|
+
initWithRect:NSZeroRect
|
|
686
|
+
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect
|
|
687
|
+
owner:self
|
|
688
|
+
userInfo:nil];
|
|
689
|
+
[self addTrackingArea:_mouseTrackingArea];
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
- (HostPlatformViewEventEmitter::MouseEvent)_mouseEventFromNSEvent:(NSEvent *)event
|
|
693
|
+
{
|
|
694
|
+
NSPoint inWindow = event.locationInWindow;
|
|
695
|
+
NSPoint inView = [self convertPoint:inWindow fromView:nil];
|
|
696
|
+
NSPoint onScreen = self.window != nil ? [self.window convertPointToScreen:inWindow] : inWindow;
|
|
697
|
+
|
|
698
|
+
HostPlatformViewEventEmitter::MouseEvent mouseEvent = {};
|
|
699
|
+
mouseEvent.clientX = inView.x;
|
|
700
|
+
mouseEvent.clientY = inView.y;
|
|
701
|
+
mouseEvent.pageX = inWindow.x;
|
|
702
|
+
mouseEvent.pageY = inWindow.y;
|
|
703
|
+
mouseEvent.screenX = onScreen.x;
|
|
704
|
+
mouseEvent.screenY = onScreen.y;
|
|
705
|
+
return mouseEvent;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
- (void)mouseEntered:(NSEvent *)event
|
|
709
|
+
{
|
|
710
|
+
[super mouseEntered:event];
|
|
711
|
+
if (_eventEmitter != nullptr) {
|
|
712
|
+
_eventEmitter->onMouseEnter([self _mouseEventFromNSEvent:event]);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
- (void)mouseExited:(NSEvent *)event
|
|
717
|
+
{
|
|
718
|
+
[super mouseExited:event];
|
|
719
|
+
if (_eventEmitter != nullptr) {
|
|
720
|
+
_eventEmitter->onMouseLeave([self _mouseEventFromNSEvent:event]);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
- (void)mouseUp:(NSEvent *)event
|
|
725
|
+
{
|
|
726
|
+
[super mouseUp:event];
|
|
727
|
+
const auto &viewProps = static_cast<const ViewProps &>(*_props);
|
|
728
|
+
if (_eventEmitter != nullptr && event.clickCount == 2 &&
|
|
729
|
+
viewProps.hostPlatformEvents[HostPlatformViewEvents::Offset::DoubleClick]) {
|
|
730
|
+
_eventEmitter->onDoubleClick([self _mouseEventFromNSEvent:event]);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
- (void)rightMouseUp:(NSEvent *)event
|
|
735
|
+
{
|
|
736
|
+
[super rightMouseUp:event];
|
|
737
|
+
const auto &viewProps = static_cast<const ViewProps &>(*_props);
|
|
738
|
+
if (_eventEmitter != nullptr && viewProps.hostPlatformEvents[HostPlatformViewEvents::Offset::AuxClick]) {
|
|
739
|
+
_eventEmitter->onAuxClick([self _mouseEventFromNSEvent:event]);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
- (BOOL)allowsVibrancy
|
|
744
|
+
{
|
|
745
|
+
return _allowsVibrancy;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
- (BOOL)mouseDownCanMoveWindow
|
|
749
|
+
{
|
|
750
|
+
return _mouseDownCanMoveWindow;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
- (BOOL)canBecomeKeyView
|
|
754
|
+
{
|
|
755
|
+
return _focusable;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
- (BOOL)acceptsFirstResponder
|
|
759
|
+
{
|
|
760
|
+
return _focusable || [super acceptsFirstResponder];
|
|
761
|
+
}
|
|
762
|
+
#endif // macOS]
|
|
763
|
+
|
|
614
764
|
- (void)updateEventEmitter:(const EventEmitter::Shared &)eventEmitter
|
|
615
765
|
{
|
|
616
766
|
assert(std::dynamic_pointer_cast<const ViewEventEmitter>(eventEmitter));
|
|
@@ -102,6 +102,10 @@ Pod::Spec.new do |s|
|
|
|
102
102
|
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/legacyviewmanagerinterop/platform/ios\"",
|
|
103
103
|
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/text/platform/cxx\"",
|
|
104
104
|
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/textinput/platform/ios\"",
|
|
105
|
+
# [macOS] macOS has its own HostPlatformViewProps -- tooltip, focus ring,
|
|
106
|
+
# first mouse and the rest. Its directory has to come first so it wins
|
|
107
|
+
# over the shared C++ one. macOS]
|
|
108
|
+
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/view/platform/macos\"",
|
|
105
109
|
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/view/platform/cxx\"",
|
|
106
110
|
]
|
|
107
111
|
end
|
|
@@ -135,6 +139,11 @@ Pod::Spec.new do |s|
|
|
|
135
139
|
sss.dependency "React-renderercss"
|
|
136
140
|
sss.dependency "Yoga"
|
|
137
141
|
sss.source_files = podspec_sources(["react/renderer/components/view/*.{m,mm,cpp,h}", "react/renderer/components/view/platform/cxx/**/*.{m,mm,cpp,h}"], ["react/renderer/components/view/*.{h}", "react/renderer/components/view/platform/cxx/**/*.{h}"])
|
|
142
|
+
# [macOS] Swap the shared C++ host-platform view files for the macOS ones.
|
|
143
|
+
# Both define the same symbols, so this is a replacement, not an addition.
|
|
144
|
+
sss.osx.source_files = podspec_sources(["react/renderer/components/view/*.{m,mm,cpp,h}", "react/renderer/components/view/platform/macos/**/*.{m,mm,cpp,h}"], ["react/renderer/components/view/*.{h}", "react/renderer/components/view/platform/macos/**/*.{h}"])
|
|
145
|
+
sss.osx.exclude_files = "react/renderer/components/view/platform/cxx/**/*"
|
|
146
|
+
# macOS]
|
|
138
147
|
sss.header_dir = "react/renderer/components/view"
|
|
139
148
|
end
|
|
140
149
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// [macOS] Touch is the shared one; a mouse is reported through the same path.
|
|
9
|
+
|
|
10
|
+
#pragma once
|
|
11
|
+
|
|
12
|
+
#include <react/renderer/components/view/BaseTouch.h>
|
|
13
|
+
|
|
14
|
+
namespace facebook::react {
|
|
15
|
+
using HostPlatformTouch = BaseTouch;
|
|
16
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// [macOS] See HostPlatformViewEventEmitter.h.
|
|
9
|
+
|
|
10
|
+
#include "HostPlatformViewEventEmitter.h"
|
|
11
|
+
|
|
12
|
+
namespace facebook::react {
|
|
13
|
+
|
|
14
|
+
static jsi::Value mouseEventPayload(jsi::Runtime &runtime, const HostPlatformViewEventEmitter::MouseEvent &event)
|
|
15
|
+
{
|
|
16
|
+
auto payload = jsi::Object(runtime);
|
|
17
|
+
payload.setProperty(runtime, "clientX", event.clientX);
|
|
18
|
+
payload.setProperty(runtime, "clientY", event.clientY);
|
|
19
|
+
payload.setProperty(runtime, "screenX", event.screenX);
|
|
20
|
+
payload.setProperty(runtime, "screenY", event.screenY);
|
|
21
|
+
payload.setProperty(runtime, "pageX", event.pageX);
|
|
22
|
+
payload.setProperty(runtime, "pageY", event.pageY);
|
|
23
|
+
return payload;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#define RCT_MACOS_MOUSE_EVENT(name) \
|
|
27
|
+
void HostPlatformViewEventEmitter::name(const MouseEvent &event) const \
|
|
28
|
+
{ \
|
|
29
|
+
dispatchEvent(#name, [event](jsi::Runtime &runtime) { \
|
|
30
|
+
return mouseEventPayload(runtime, event); \
|
|
31
|
+
}); \
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
RCT_MACOS_MOUSE_EVENT(onMouseEnter)
|
|
35
|
+
RCT_MACOS_MOUSE_EVENT(onMouseLeave)
|
|
36
|
+
RCT_MACOS_MOUSE_EVENT(onDoubleClick)
|
|
37
|
+
RCT_MACOS_MOUSE_EVENT(onAuxClick)
|
|
38
|
+
|
|
39
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// [macOS] Adds the pointer events AppKit can report and UIKit cannot.
|
|
9
|
+
|
|
10
|
+
#pragma once
|
|
11
|
+
|
|
12
|
+
#include <react/renderer/components/view/BaseViewEventEmitter.h>
|
|
13
|
+
|
|
14
|
+
namespace facebook::react {
|
|
15
|
+
|
|
16
|
+
class HostPlatformViewEventEmitter : public BaseViewEventEmitter {
|
|
17
|
+
public:
|
|
18
|
+
using BaseViewEventEmitter::BaseViewEventEmitter;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A mouse crossing into or out of the view. There is no touch equivalent, so
|
|
22
|
+
* these have no counterpart in BaseViewEventEmitter.
|
|
23
|
+
*/
|
|
24
|
+
struct MouseEvent {
|
|
25
|
+
Float clientX{};
|
|
26
|
+
Float clientY{};
|
|
27
|
+
Float screenX{};
|
|
28
|
+
Float screenY{};
|
|
29
|
+
Float pageX{};
|
|
30
|
+
Float pageY{};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
void onMouseEnter(const MouseEvent &event) const;
|
|
34
|
+
void onMouseLeave(const MouseEvent &event) const;
|
|
35
|
+
void onDoubleClick(const MouseEvent &event) const;
|
|
36
|
+
void onAuxClick(const MouseEvent &event) const;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// [macOS] Which macOS-only handlers a view actually has.
|
|
9
|
+
//
|
|
10
|
+
// Installing an NSTrackingArea on every view to find out later would cost a
|
|
11
|
+
// mouse-moved dispatch per view per move. The props carry a bitset instead, so
|
|
12
|
+
// the view only tracks the mouse when something is listening -- the same
|
|
13
|
+
// arrangement BaseViewProps uses for pointer and responder events.
|
|
14
|
+
|
|
15
|
+
#pragma once
|
|
16
|
+
|
|
17
|
+
#include <bitset>
|
|
18
|
+
#include <cstddef>
|
|
19
|
+
|
|
20
|
+
namespace facebook::react {
|
|
21
|
+
|
|
22
|
+
struct HostPlatformViewEvents {
|
|
23
|
+
std::bitset<8> bits{};
|
|
24
|
+
|
|
25
|
+
enum class Offset : std::size_t {
|
|
26
|
+
MouseEnter = 0,
|
|
27
|
+
MouseLeave = 1,
|
|
28
|
+
DoubleClick = 2,
|
|
29
|
+
AuxClick = 3,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
constexpr bool operator[](Offset offset) const
|
|
33
|
+
{
|
|
34
|
+
return bits[static_cast<std::size_t>(offset)];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
std::bitset<8>::reference operator[](Offset offset)
|
|
38
|
+
{
|
|
39
|
+
return bits[static_cast<std::size_t>(offset)];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** True when any macOS mouse handler is present. */
|
|
43
|
+
bool wantsMouseTracking() const
|
|
44
|
+
{
|
|
45
|
+
return (*this)[Offset::MouseEnter] || (*this)[Offset::MouseLeave];
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
inline bool operator==(const HostPlatformViewEvents &lhs, const HostPlatformViewEvents &rhs)
|
|
50
|
+
{
|
|
51
|
+
return lhs.bits == rhs.bits;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
inline bool operator!=(const HostPlatformViewEvents &lhs, const HostPlatformViewEvents &rhs)
|
|
55
|
+
{
|
|
56
|
+
return lhs.bits != rhs.bits;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// [macOS] See HostPlatformViewProps.h.
|
|
9
|
+
|
|
10
|
+
#include "HostPlatformViewProps.h"
|
|
11
|
+
|
|
12
|
+
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
|
13
|
+
#include <react/renderer/core/propsConversions.h>
|
|
14
|
+
|
|
15
|
+
namespace facebook::react {
|
|
16
|
+
|
|
17
|
+
// The whole-map parsing path (feature flag off) needs a converter for the
|
|
18
|
+
// bitset, mirroring the one propsConversions.h provides for ViewEvents.
|
|
19
|
+
static inline HostPlatformViewEvents convertRawProp(
|
|
20
|
+
const PropsParserContext &context,
|
|
21
|
+
const RawProps &rawProps,
|
|
22
|
+
const HostPlatformViewEvents &sourceValue,
|
|
23
|
+
const HostPlatformViewEvents &defaultValue)
|
|
24
|
+
{
|
|
25
|
+
HostPlatformViewEvents result{};
|
|
26
|
+
using Offset = HostPlatformViewEvents::Offset;
|
|
27
|
+
|
|
28
|
+
#define RCT_MACOS_CONVERT_EVENT(name, offset) \
|
|
29
|
+
result[Offset::offset] = convertRawProp( \
|
|
30
|
+
context, rawProps, name, sourceValue[Offset::offset], defaultValue[Offset::offset])
|
|
31
|
+
|
|
32
|
+
RCT_MACOS_CONVERT_EVENT("onMouseEnter", MouseEnter);
|
|
33
|
+
RCT_MACOS_CONVERT_EVENT("onMouseLeave", MouseLeave);
|
|
34
|
+
RCT_MACOS_CONVERT_EVENT("onDoubleClick", DoubleClick);
|
|
35
|
+
RCT_MACOS_CONVERT_EVENT("onAuxClick", AuxClick);
|
|
36
|
+
|
|
37
|
+
#undef RCT_MACOS_CONVERT_EVENT
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Two parsing paths exist and both have to be fed. With the iterator setter
|
|
43
|
+
// feature flag on, props arrive one at a time through setProp and the
|
|
44
|
+
// constructor just carries the previous value forward; with it off, the
|
|
45
|
+
// constructor parses the whole RawProps map itself.
|
|
46
|
+
#define RCT_MACOS_PROP(name) \
|
|
47
|
+
name(ReactNativeFeatureFlags::enableCppPropsIteratorSetter() \
|
|
48
|
+
? sourceProps.name \
|
|
49
|
+
: convertRawProp(context, rawProps, #name, sourceProps.name, {}))
|
|
50
|
+
|
|
51
|
+
HostPlatformViewProps::HostPlatformViewProps(
|
|
52
|
+
const PropsParserContext &context,
|
|
53
|
+
const HostPlatformViewProps &sourceProps,
|
|
54
|
+
const RawProps &rawProps)
|
|
55
|
+
: BaseViewProps(context, sourceProps, rawProps),
|
|
56
|
+
hostPlatformEvents(
|
|
57
|
+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
|
58
|
+
? sourceProps.hostPlatformEvents
|
|
59
|
+
: convertRawProp(context, rawProps, sourceProps.hostPlatformEvents, {})),
|
|
60
|
+
RCT_MACOS_PROP(focusable),
|
|
61
|
+
RCT_MACOS_PROP(enableFocusRing),
|
|
62
|
+
RCT_MACOS_PROP(tooltip),
|
|
63
|
+
RCT_MACOS_PROP(acceptsFirstMouse),
|
|
64
|
+
RCT_MACOS_PROP(allowsVibrancy),
|
|
65
|
+
RCT_MACOS_PROP(mouseDownCanMoveWindow)
|
|
66
|
+
{
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#undef RCT_MACOS_PROP
|
|
70
|
+
|
|
71
|
+
void HostPlatformViewProps::setProp(
|
|
72
|
+
const PropsParserContext &context,
|
|
73
|
+
RawPropsPropNameHash hash,
|
|
74
|
+
const char *propName,
|
|
75
|
+
const RawValue &value)
|
|
76
|
+
{
|
|
77
|
+
// Every Props struct must call super unconditionally: several structs can
|
|
78
|
+
// share the same raw value, and skipping the call drops it for all of them.
|
|
79
|
+
BaseViewProps::setProp(context, hash, propName, value);
|
|
80
|
+
|
|
81
|
+
static auto defaults = HostPlatformViewProps{};
|
|
82
|
+
|
|
83
|
+
// An `onX` prop is stored as a bit rather than a value: all the view needs to
|
|
84
|
+
// know is whether anything is listening.
|
|
85
|
+
#define RCT_MACOS_EVENT_CASE(eventType) \
|
|
86
|
+
case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
|
|
87
|
+
const auto offset = HostPlatformViewEvents::Offset::eventType; \
|
|
88
|
+
HostPlatformViewEvents defaultEvents{}; \
|
|
89
|
+
bool listening = defaultEvents[offset]; \
|
|
90
|
+
if (value.hasValue()) { \
|
|
91
|
+
fromRawValue(context, value, listening); \
|
|
92
|
+
} \
|
|
93
|
+
hostPlatformEvents[offset] = listening; \
|
|
94
|
+
return; \
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
switch (hash) {
|
|
98
|
+
RCT_MACOS_EVENT_CASE(MouseEnter);
|
|
99
|
+
RCT_MACOS_EVENT_CASE(MouseLeave);
|
|
100
|
+
RCT_MACOS_EVENT_CASE(DoubleClick);
|
|
101
|
+
RCT_MACOS_EVENT_CASE(AuxClick);
|
|
102
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(focusable);
|
|
103
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(enableFocusRing);
|
|
104
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(tooltip);
|
|
105
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(acceptsFirstMouse);
|
|
106
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(allowsVibrancy);
|
|
107
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(mouseDownCanMoveWindow);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
#undef RCT_MACOS_EVENT_CASE
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// [macOS] The props a Mac view has and an iOS one does not.
|
|
9
|
+
//
|
|
10
|
+
// React Native reaches platform-specific view props through this class -- see
|
|
11
|
+
// the sibling directories under components/view/platform. Adding them here
|
|
12
|
+
// means no shared C++ changes at all, and the names match
|
|
13
|
+
// microsoft/react-native-macos so code written against that fork type-checks
|
|
14
|
+
// and behaves the same.
|
|
15
|
+
|
|
16
|
+
#pragma once
|
|
17
|
+
|
|
18
|
+
#include <react/renderer/components/view/BaseViewProps.h>
|
|
19
|
+
#include <react/renderer/core/PropsParserContext.h>
|
|
20
|
+
|
|
21
|
+
#include <optional>
|
|
22
|
+
#include <string>
|
|
23
|
+
|
|
24
|
+
#include "HostPlatformViewEvents.h"
|
|
25
|
+
|
|
26
|
+
namespace facebook::react {
|
|
27
|
+
|
|
28
|
+
class HostPlatformViewProps : public BaseViewProps {
|
|
29
|
+
public:
|
|
30
|
+
HostPlatformViewProps() = default;
|
|
31
|
+
HostPlatformViewProps(
|
|
32
|
+
const PropsParserContext &context,
|
|
33
|
+
const HostPlatformViewProps &sourceProps,
|
|
34
|
+
const RawProps &rawProps);
|
|
35
|
+
|
|
36
|
+
void
|
|
37
|
+
setProp(const PropsParserContext &context, RawPropsPropNameHash hash, const char *propName, const RawValue &value);
|
|
38
|
+
|
|
39
|
+
/** Which macOS-only handlers are attached; see HostPlatformViewEvents. */
|
|
40
|
+
HostPlatformViewEvents hostPlatformEvents{};
|
|
41
|
+
|
|
42
|
+
#pragma mark - Props
|
|
43
|
+
|
|
44
|
+
/** Participates in the key view loop, i.e. reachable by Tab. */
|
|
45
|
+
bool focusable{false};
|
|
46
|
+
|
|
47
|
+
/** Draws the focus ring while first responder. On by default, as in AppKit. */
|
|
48
|
+
bool enableFocusRing{true};
|
|
49
|
+
|
|
50
|
+
/** The view's help tag. std::nullopt leaves any inherited tooltip alone. */
|
|
51
|
+
std::optional<std::string> tooltip{};
|
|
52
|
+
|
|
53
|
+
/** Take the click that activates a background window, rather than swallowing it. */
|
|
54
|
+
bool acceptsFirstMouse{false};
|
|
55
|
+
|
|
56
|
+
/** Let the view sit in an NSVisualEffectView and blend with what is behind it. */
|
|
57
|
+
bool allowsVibrancy{false};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Whether dragging the view moves the window. AppKit's default is true, and
|
|
61
|
+
* that is kept here: a view that opts out is the interesting case.
|
|
62
|
+
*/
|
|
63
|
+
bool mouseDownCanMoveWindow{true};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// [macOS] Keyboard focus is a real thing on macOS, so unlike the shared C++
|
|
9
|
+
// initializer this reports `focusable` views as keyboard-focusable.
|
|
10
|
+
|
|
11
|
+
#pragma once
|
|
12
|
+
|
|
13
|
+
#include <react/renderer/components/view/ViewProps.h>
|
|
14
|
+
#include <react/renderer/core/ShadowNodeTraits.h>
|
|
15
|
+
|
|
16
|
+
namespace facebook::react::HostPlatformViewTraitsInitializer {
|
|
17
|
+
|
|
18
|
+
inline bool formsStackingContext(const ViewProps & /*props*/)
|
|
19
|
+
{
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
inline bool formsView(const ViewProps &props)
|
|
24
|
+
{
|
|
25
|
+
// These all need a backing NSView, so a view carrying any of them must not be
|
|
26
|
+
// flattened away: a focusable view has to join the key view loop, a tooltip
|
|
27
|
+
// has to attach to something, and mouse tracking needs an NSTrackingArea
|
|
28
|
+
// owner. Flattening is otherwise invisible -- the handler simply never fires.
|
|
29
|
+
return props.focusable || props.tooltip.has_value() || props.hostPlatformEvents.bits.any();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
inline bool isKeyboardFocusable(const ViewProps &props)
|
|
33
|
+
{
|
|
34
|
+
return props.focusable;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
} // namespace facebook::react::HostPlatformViewTraitsInitializer
|
package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h
CHANGED
|
@@ -30,6 +30,12 @@ struct Color {
|
|
|
30
30
|
|
|
31
31
|
static Color createSemanticColor(std::vector<std::string> &semanticItems);
|
|
32
32
|
|
|
33
|
+
#if TARGET_OS_OSX // [macOS] Wrap an already-resolved NSColor. AppKit derives some
|
|
34
|
+
// colours from others -- colorWithSystemEffect: -- so the parser needs a way
|
|
35
|
+
// to hand back a colour it built itself. macOS]
|
|
36
|
+
static Color createFromHostPlatformColor(std::shared_ptr<void> hostPlatformColor);
|
|
37
|
+
#endif
|
|
38
|
+
|
|
33
39
|
std::shared_ptr<void> getUIColor() const
|
|
34
40
|
{
|
|
35
41
|
return uiColor_;
|
|
@@ -95,6 +95,13 @@ int32_t ColorFromColorComponents(const facebook::react::ColorComponents &compone
|
|
|
95
95
|
int32_t ColorFromUIColor(UIColor *color)
|
|
96
96
|
{
|
|
97
97
|
CGFloat rgba[4];
|
|
98
|
+
#if TARGET_OS_OSX // [macOS] catalog colours need converting first; see Color::getChannel
|
|
99
|
+
NSColor *rgbColor = [color colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
|
|
100
|
+
if (rgbColor == nil) {
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
color = rgbColor;
|
|
104
|
+
#endif // macOS]
|
|
98
105
|
[color getRed:&rgba[0] green:&rgba[1] blue:&rgba[2] alpha:&rgba[3]];
|
|
99
106
|
return ColorFromColorComponents(
|
|
100
107
|
{.red = (float)rgba[0], .green = (float)rgba[1], .blue = (float)rgba[2], .alpha = (float)rgba[3]});
|
|
@@ -226,6 +233,23 @@ float Color::getChannel(int channelId) const
|
|
|
226
233
|
{
|
|
227
234
|
CGFloat rgba[4];
|
|
228
235
|
UIColor *color = (__bridge UIColor *)getUIColor().get();
|
|
236
|
+
#if TARGET_OS_OSX // [macOS
|
|
237
|
+
// AppKit's named colours -- everything PlatformColor() resolves to, plus the
|
|
238
|
+
// system palette -- live in the Catalog colour space, and asking one for its
|
|
239
|
+
// RGBA components without converting first raises:
|
|
240
|
+
//
|
|
241
|
+
// -getRed:green:blue:alpha: not valid for the NSColor Catalog color
|
|
242
|
+
//
|
|
243
|
+
// sRGB is the right target: it is what the components are interpreted as
|
|
244
|
+
// everywhere else in the renderer.
|
|
245
|
+
NSColor *rgbColor = [color colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
|
|
246
|
+
if (rgbColor == nil) {
|
|
247
|
+
// A pattern or otherwise unconvertible colour. Treat it as transparent
|
|
248
|
+
// rather than raising, which would take the whole app down.
|
|
249
|
+
return 0;
|
|
250
|
+
}
|
|
251
|
+
color = rgbColor;
|
|
252
|
+
#endif // macOS]
|
|
229
253
|
[color getRed:&rgba[0] green:&rgba[1] blue:&rgba[2] alpha:&rgba[3]];
|
|
230
254
|
return static_cast<float>(rgba[channelId]);
|
|
231
255
|
}
|
|
@@ -235,6 +259,13 @@ std::size_t Color::getUIColorHash() const
|
|
|
235
259
|
return uiColorHashValue_;
|
|
236
260
|
}
|
|
237
261
|
|
|
262
|
+
#if TARGET_OS_OSX // [macOS
|
|
263
|
+
Color Color::createFromHostPlatformColor(std::shared_ptr<void> hostPlatformColor)
|
|
264
|
+
{
|
|
265
|
+
return Color(std::move(hostPlatformColor));
|
|
266
|
+
}
|
|
267
|
+
#endif // macOS]
|
|
268
|
+
|
|
238
269
|
Color Color::createSemanticColor(std::vector<std::string> &semanticItems)
|
|
239
270
|
{
|
|
240
271
|
auto semanticColor = RCTPlatformColorFromSemanticItems(semanticItems);
|
|
@@ -63,6 +63,40 @@ SharedColor parsePlatformColor(const ContextContainer &contextContainer, int32_t
|
|
|
63
63
|
items.at("dynamic").hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
64
64
|
auto dynamicItems = (std::unordered_map<std::string, RawValue>)items.at("dynamic");
|
|
65
65
|
return RCTPlatformColorComponentsFromDynamicItems(contextContainer, surfaceId, dynamicItems);
|
|
66
|
+
#if TARGET_OS_OSX // [macOS
|
|
67
|
+
} else if (
|
|
68
|
+
items.find("colorWithSystemEffect") != items.end() &&
|
|
69
|
+
items.at("colorWithSystemEffect").hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
70
|
+
// AppKit derives the pressed / disabled / rollover variant of a colour
|
|
71
|
+
// rather than making the caller supply it. UIKit has no equivalent, so
|
|
72
|
+
// this arm only exists here.
|
|
73
|
+
auto effectItems = (std::unordered_map<std::string, RawValue>)items.at("colorWithSystemEffect");
|
|
74
|
+
if (effectItems.count("baseColor") == 0u || effectItems.count("systemEffect") == 0u) {
|
|
75
|
+
return clearColor();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
SharedColor baseSharedColor;
|
|
79
|
+
fromRawValue(contextContainer, surfaceId, effectItems.at("baseColor"), baseSharedColor);
|
|
80
|
+
auto effectName = (std::string)effectItems.at("systemEffect");
|
|
81
|
+
|
|
82
|
+
static const std::unordered_map<std::string, NSColorSystemEffect> effects = {
|
|
83
|
+
{"none", NSColorSystemEffectNone},
|
|
84
|
+
{"pressed", NSColorSystemEffectPressed},
|
|
85
|
+
{"deepPressed", NSColorSystemEffectDeepPressed},
|
|
86
|
+
{"disabled", NSColorSystemEffectDisabled},
|
|
87
|
+
{"rollover", NSColorSystemEffectRollover}};
|
|
88
|
+
|
|
89
|
+
auto effect = effects.find(effectName);
|
|
90
|
+
if (effect == effects.end()) {
|
|
91
|
+
return clearColor();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
NSColor *baseColor = RCTPlatformColorFromColor(*baseSharedColor);
|
|
95
|
+
if (baseColor == nil) {
|
|
96
|
+
return clearColor();
|
|
97
|
+
}
|
|
98
|
+
return SharedColor(Color::createFromHostPlatformColor(wrapManagedObject([baseColor colorWithSystemEffect:effect->second])));
|
|
99
|
+
#endif // macOS]
|
|
66
100
|
}
|
|
67
101
|
}
|
|
68
102
|
|