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.
Files changed (24) hide show
  1. package/Libraries/Components/View/ViewPropTypes.js +58 -0
  2. package/Libraries/NativeComponent/BaseViewConfig.macos.js +66 -11
  3. package/Libraries/NativeComponent/ViewConfigIgnore.js +5 -1
  4. package/Libraries/StyleSheet/PlatformColorValueTypes.macos.js +147 -10
  5. package/Libraries/StyleSheet/PlatformColorValueTypesMacOS.js +34 -0
  6. package/Libraries/StyleSheet/PlatformColorValueTypesMacOS.macos.js +55 -0
  7. package/Libraries/Utilities/Platform.macos.js +78 -11
  8. package/React/Base/RCTConvert.mm +49 -0
  9. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +150 -0
  10. package/ReactCommon/React-Fabric.podspec +9 -0
  11. package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h +16 -0
  12. package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +39 -0
  13. package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h +39 -0
  14. package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h +59 -0
  15. package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp +113 -0
  16. package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h +66 -0
  17. package/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +37 -0
  18. package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h +6 -0
  19. package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.mm +31 -0
  20. package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.mm +34 -0
  21. package/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/RCTPlatformColorUtils.mm +23 -0
  22. package/index.js +10 -0
  23. package/macos/UIKitCompat/UIKit/UIColor.m +7 -1
  24. package/package.json +1 -1
@@ -128,6 +128,63 @@ type FocusEventProps = Readonly<{
128
128
  onFocusCapture?: ?(event: FocusEvent) => void,
129
129
  }>;
130
130
 
131
+ // [macOS] Props that only exist on macOS. They are declared here rather than in
132
+ // a .macos file because ViewPropTypes is shared, and a prop that is simply
133
+ // absent on other platforms costs them nothing. The native side is
134
+ // HostPlatformViewProps under components/view/platform/macos. macOS]
135
+ type MacOSViewProps = Readonly<{
136
+ /**
137
+ * The view's help tag, shown when the pointer rests over it.
138
+ *
139
+ * @platform macos
140
+ */
141
+ tooltip?: ?string,
142
+
143
+ /**
144
+ * Receive the click that activates a background window, rather than letting
145
+ * it be swallowed to bring the window forward.
146
+ *
147
+ * @platform macos
148
+ */
149
+ acceptsFirstMouse?: ?boolean,
150
+
151
+ /**
152
+ * Let the view blend with what is behind it when inside a vibrancy effect.
153
+ *
154
+ * @platform macos
155
+ */
156
+ allowsVibrancy?: ?boolean,
157
+
158
+ /**
159
+ * Draw the focus ring while the view is first responder. Defaults to true.
160
+ *
161
+ * @platform macos
162
+ */
163
+ enableFocusRing?: ?boolean,
164
+
165
+ /**
166
+ * Whether dragging the view moves the window. AppKit defaults this to true;
167
+ * set it false for a view that should handle its own drags.
168
+ *
169
+ * @platform macos
170
+ */
171
+ mouseDownCanMoveWindow?: ?boolean,
172
+
173
+ /**
174
+ * Called on a double click.
175
+ *
176
+ * @platform macos
177
+ */
178
+ onDoubleClick?: ?(event: MouseEvent) => void,
179
+
180
+ /**
181
+ * Called on a secondary (right) click.
182
+ *
183
+ * @platform macos
184
+ */
185
+ onAuxClick?: ?(event: MouseEvent) => void,
186
+ }>;
187
+
131
188
  type KeyEventProps = Readonly<{
132
189
  onKeyDown?: ?(event: KeyDownEvent) => void,
133
190
  onKeyDownCapture?: ?(event: KeyDownEvent) => void,
@@ -566,6 +623,7 @@ export type ViewProps = Readonly<{
566
623
  ...DirectEventProps,
567
624
  ...GestureResponderHandlers,
568
625
  ...MouseEventProps,
626
+ ...MacOSViewProps, // [macOS]
569
627
  ...PointerEventProps,
570
628
  ...FocusEventProps,
571
629
  ...KeyEventProps,
@@ -1,4 +1,4 @@
1
- /*
1
+ /**
2
2
  * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
@@ -8,16 +8,71 @@
8
8
  * @format
9
9
  */
10
10
 
11
- // [macOS] macOS resolves as `.macos` -> `.native` -> shared, so without this
12
- // file `BaseViewConfig` re-exports itself: the shared file is a
13
- // stub that expects a platform-suffixed sibling to answer. Point it at the iOS
14
- // implementation, which is what this fork uses on macOS wherever upstream has
15
- // no platform-neutral one. macOS]
11
+ // [macOS] The view config decides which props reach native at all: anything
12
+ // missing from `validAttributes` is dropped before it ever gets to C++. So the
13
+ // macOS-only props declared in HostPlatformViewProps have to be listed here as
14
+ // well, or setting them does nothing.
15
+ //
16
+ // Everything iOS declares still applies, so this extends that config rather
17
+ // than replacing it. Names match microsoft/react-native-macos. macOS]
16
18
 
17
- // NOTE: This file supports backwards compatibility of subpath (deep) imports
18
- // from 'react-native' with platform-specific extensions. It can be deleted
19
- // once we remove the "./*" mapping from package.json "exports".
19
+ import type {PartialViewConfigWithoutName} from './PlatformBaseViewConfig';
20
20
 
21
- import BaseViewConfig from './BaseViewConfig.ios';
21
+ // $FlowFixMe[cannot-resolve-module] macOS shares the iOS base config.
22
+ import PlatformBaseViewConfigIOS from './BaseViewConfig.ios';
23
+ import {ConditionallyIgnoredEventHandlers} from './ViewConfigIgnore';
22
24
 
23
- export default BaseViewConfig;
25
+ const bubblingEventTypes = {
26
+ ...PlatformBaseViewConfigIOS.bubblingEventTypes,
27
+ topKeyDown: {
28
+ phasedRegistrationNames: {
29
+ captured: 'onKeyDownCapture',
30
+ bubbled: 'onKeyDown',
31
+ },
32
+ },
33
+ topKeyUp: {
34
+ phasedRegistrationNames: {
35
+ captured: 'onKeyUpCapture',
36
+ bubbled: 'onKeyUp',
37
+ },
38
+ },
39
+ };
40
+
41
+ const directEventTypes = {
42
+ ...PlatformBaseViewConfigIOS.directEventTypes,
43
+ topDoubleClick: {registrationName: 'onDoubleClick'},
44
+ topAuxClick: {registrationName: 'onAuxClick'},
45
+ topMouseEnter: {registrationName: 'onMouseEnter'},
46
+ topMouseLeave: {registrationName: 'onMouseLeave'},
47
+ };
48
+
49
+ const validAttributesForNonEventProps = {
50
+ acceptsFirstMouse: true,
51
+ allowsVibrancy: true,
52
+ enableFocusRing: true,
53
+ focusable: true,
54
+ mouseDownCanMoveWindow: true,
55
+ tooltip: true,
56
+ };
57
+
58
+ const validAttributesForEventProps = ConditionallyIgnoredEventHandlers({
59
+ onAuxClick: true,
60
+ onDoubleClick: true,
61
+ onKeyDown: true,
62
+ onKeyUp: true,
63
+ onMouseEnter: true,
64
+ onMouseLeave: true,
65
+ });
66
+
67
+ const PlatformBaseViewConfigMacOS: PartialViewConfigWithoutName = {
68
+ bubblingEventTypes,
69
+ directEventTypes,
70
+ validAttributes: {
71
+ ...PlatformBaseViewConfigIOS.validAttributes,
72
+ ...validAttributesForNonEventProps,
73
+ // $FlowFixMe[exponential-spread]
74
+ ...validAttributesForEventProps,
75
+ },
76
+ };
77
+
78
+ export default PlatformBaseViewConfigMacOS;
@@ -39,7 +39,11 @@ export function DynamicallyInjectedByGestureHandler<T extends {...}>(
39
39
  export function ConditionallyIgnoredEventHandlers<
40
40
  const T extends {readonly [name: string]: true},
41
41
  >(value: T): T | void {
42
- if (Platform.OS === 'ios') {
42
+ // [macOS] macOS declares its view props the same way iOS does, so it keeps
43
+ // these too. Reporting Platform.OS as 'macos' without this drops every event
44
+ // handler in the base view config -- including iOS's own -- and nothing that
45
+ // depends on them ever fires. macOS]
46
+ if (Platform.OS === 'ios' || Platform.OS === 'macos') {
43
47
  return value;
44
48
  }
45
49
  return undefined;
@@ -1,4 +1,4 @@
1
- /*
1
+ /**
2
2
  * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
@@ -8,14 +8,151 @@
8
8
  * @format
9
9
  */
10
10
 
11
- // [macOS] macOS resolves as `.macos` -> `.native` -> shared, so without this
12
- // file `PlatformColorValueTypes` re-exports itself: the shared file is a
13
- // stub that expects a platform-suffixed sibling to answer. Point it at the iOS
14
- // implementation, which is what this fork uses on macOS wherever upstream has
15
- // no platform-neutral one. macOS]
11
+ // [macOS] The macOS colour types.
12
+ //
13
+ // `semantic` and `dynamic` carry over from iOS unchanged -- RCTConvert resolves
14
+ // both on this platform, and semantic names are looked up on NSColor, so
15
+ // AppKit's whole vocabulary (labelColor, windowBackgroundColor,
16
+ // controlAccentColor, ...) works. What iOS has no equivalent for is
17
+ // `colorWithSystemEffect`, AppKit's pressed / disabled / rollover variants of a
18
+ // colour, so that is added here. macOS]
16
19
 
17
- // NOTE: This file supports backwards compatibility of subpath (deep) imports
18
- // from 'react-native' with platform-specific extensions. It can be deleted
19
- // once we remove the "./*" mapping from package.json "exports".
20
20
 
21
- export * from './PlatformColorValueTypes.ios';
21
+ import type {ProcessedColorValue} from './processColor';
22
+ import type {ColorValue, NativeColorValue} from './StyleSheet';
23
+
24
+ /** The actual type of the opaque NativeColorValue on macOS platform */
25
+ type LocalNativeColorValue = {
26
+ semantic?: Array<string>,
27
+ colorWithSystemEffect?: {
28
+ baseColor: ?(ColorValue | ProcessedColorValue),
29
+ systemEffect: string,
30
+ },
31
+ dynamic?: {
32
+ light: ?(ColorValue | ProcessedColorValue),
33
+ dark: ?(ColorValue | ProcessedColorValue),
34
+ highContrastLight?: ?(ColorValue | ProcessedColorValue),
35
+ highContrastDark?: ?(ColorValue | ProcessedColorValue),
36
+ },
37
+ };
38
+
39
+ export const PlatformColor = (...names: Array<string>): NativeColorValue => {
40
+ // $FlowExpectedError[incompatible-type] LocalNativeColorValue is the iOS LocalNativeColorValue type
41
+ return {semantic: names} as LocalNativeColorValue;
42
+ };
43
+
44
+ export type DynamicColorMacOSTuplePrivate = {
45
+ light: ColorValue,
46
+ dark: ColorValue,
47
+ highContrastLight?: ColorValue,
48
+ highContrastDark?: ColorValue,
49
+ };
50
+
51
+ export const DynamicColorMacOSPrivate = (
52
+ tuple: DynamicColorMacOSTuplePrivate,
53
+ ): ColorValue => {
54
+ return {
55
+ dynamic: {
56
+ light: tuple.light,
57
+ dark: tuple.dark,
58
+ highContrastLight: tuple.highContrastLight,
59
+ highContrastDark: tuple.highContrastDark,
60
+ },
61
+ /* $FlowExpectedError[incompatible-type]
62
+ * LocalNativeColorValue is the actual type of the opaque NativeColorValue on macOS platform */
63
+ } as LocalNativeColorValue;
64
+ };
65
+
66
+ export type SystemEffectMacOSPrivate =
67
+ | 'none'
68
+ | 'pressed'
69
+ | 'deepPressed'
70
+ | 'disabled'
71
+ | 'rollover';
72
+
73
+ export const ColorWithSystemEffectMacOSPrivate = (
74
+ color: ColorValue,
75
+ effect: SystemEffectMacOSPrivate,
76
+ ): ColorValue => {
77
+ return {
78
+ colorWithSystemEffect: {
79
+ baseColor: color,
80
+ systemEffect: effect,
81
+ },
82
+ /* $FlowExpectedError[incompatible-type]
83
+ * LocalNativeColorValue is the actual type of the opaque NativeColorValue */
84
+ } as LocalNativeColorValue;
85
+ };
86
+
87
+ const _normalizeColorObject = (
88
+ color: LocalNativeColorValue,
89
+ ): ?LocalNativeColorValue => {
90
+ if ('colorWithSystemEffect' in color && color.colorWithSystemEffect !== undefined) {
91
+ const normalizeColor = require('./normalizeColor').default;
92
+ const spec = color.colorWithSystemEffect;
93
+ return {
94
+ colorWithSystemEffect: {
95
+ // $FlowFixMe[incompatible-call]
96
+ baseColor: normalizeColor(spec.baseColor),
97
+ systemEffect: spec.systemEffect,
98
+ },
99
+ };
100
+ } else if ('semantic' in color) {
101
+ // an AppKit or iOS semantic colour
102
+ return color;
103
+ } else if ('dynamic' in color && color.dynamic !== undefined) {
104
+ const normalizeColor = require('./normalizeColor').default;
105
+
106
+ // a dynamic, appearance aware color
107
+ const dynamic = color.dynamic;
108
+ const dynamicColor: LocalNativeColorValue = {
109
+ dynamic: {
110
+ // $FlowFixMe[incompatible-use]
111
+ light: normalizeColor(dynamic.light),
112
+ // $FlowFixMe[incompatible-use]
113
+ dark: normalizeColor(dynamic.dark),
114
+ // $FlowFixMe[incompatible-use]
115
+ highContrastLight: normalizeColor(dynamic.highContrastLight),
116
+ // $FlowFixMe[incompatible-use]
117
+ highContrastDark: normalizeColor(dynamic.highContrastDark),
118
+ },
119
+ };
120
+ return dynamicColor;
121
+ }
122
+ return null;
123
+ };
124
+
125
+ export const normalizeColorObject: (
126
+ color: NativeColorValue,
127
+ /* $FlowExpectedError[incompatible-type]
128
+ * LocalNativeColorValue is the actual type of the opaque NativeColorValue on macOS platform */
129
+ ) => ?ProcessedColorValue = _normalizeColorObject;
130
+
131
+ const _processColorObject = (
132
+ color: LocalNativeColorValue,
133
+ ): ?LocalNativeColorValue => {
134
+ if ('dynamic' in color && color.dynamic != null) {
135
+ const processColor = require('./processColor').default;
136
+ const dynamic = color.dynamic;
137
+ const dynamicColor: LocalNativeColorValue = {
138
+ dynamic: {
139
+ // $FlowFixMe[incompatible-use]
140
+ light: processColor(dynamic.light),
141
+ // $FlowFixMe[incompatible-use]
142
+ dark: processColor(dynamic.dark),
143
+ // $FlowFixMe[incompatible-use]
144
+ highContrastLight: processColor(dynamic.highContrastLight),
145
+ // $FlowFixMe[incompatible-use]
146
+ highContrastDark: processColor(dynamic.highContrastDark),
147
+ },
148
+ };
149
+ return dynamicColor;
150
+ }
151
+ return color;
152
+ };
153
+
154
+ export const processColorObject: (
155
+ color: NativeColorValue,
156
+ /* $FlowExpectedError[incompatible-type]
157
+ * LocalNativeColorValue is the actual type of the opaque NativeColorValue on macOS platform */
158
+ ) => ?NativeColorValue = _processColorObject;
@@ -0,0 +1,34 @@
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
+ * @flow strict-local
8
+ * @format
9
+ */
10
+
11
+ // [macOS] The off-macOS stand-in, matching how PlatformColorValueTypesIOS.js
12
+ // behaves elsewhere: importing is fine, calling is not.
13
+
14
+ import type {ColorValue} from './StyleSheet';
15
+
16
+ export type DynamicColorMacOSTuple = {
17
+ light: ColorValue,
18
+ dark: ColorValue,
19
+ highContrastLight?: ColorValue,
20
+ highContrastDark?: ColorValue,
21
+ };
22
+
23
+ export const DynamicColorMacOS = (_tuple: DynamicColorMacOSTuple): ColorValue => {
24
+ throw new Error('DynamicColorMacOS is not available on this platform.');
25
+ };
26
+
27
+ export type SystemEffectMacOS = 'none' | 'pressed' | 'deepPressed' | 'disabled' | 'rollover';
28
+
29
+ export const ColorWithSystemEffectMacOS = (
30
+ _color: ColorValue,
31
+ _effect: SystemEffectMacOS,
32
+ ): ColorValue => {
33
+ throw new Error('ColorWithSystemEffectMacOS is not available on this platform.');
34
+ };
@@ -0,0 +1,55 @@
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
+ * @flow strict-local
8
+ * @format
9
+ */
10
+
11
+ // [macOS] The public macOS colour API, mirroring PlatformColorValueTypesIOS.
12
+
13
+ 'use strict';
14
+
15
+ import type {ColorValue} from './StyleSheet';
16
+
17
+ import {
18
+ ColorWithSystemEffectMacOSPrivate,
19
+ DynamicColorMacOSPrivate,
20
+ // $FlowFixMe[cannot-resolve-module] resolved by the macOS platform extension
21
+ } from './PlatformColorValueTypes.macos';
22
+
23
+ export type DynamicColorMacOSTuple = {
24
+ light: ColorValue,
25
+ dark: ColorValue,
26
+ highContrastLight?: ColorValue,
27
+ highContrastDark?: ColorValue,
28
+ };
29
+
30
+ /**
31
+ * A colour that follows the system appearance, the macOS counterpart of
32
+ * `DynamicColorIOS`.
33
+ */
34
+ export const DynamicColorMacOS = (tuple: DynamicColorMacOSTuple): ColorValue => {
35
+ return DynamicColorMacOSPrivate({
36
+ light: tuple.light,
37
+ dark: tuple.dark,
38
+ highContrastLight: tuple.highContrastLight,
39
+ highContrastDark: tuple.highContrastDark,
40
+ });
41
+ };
42
+
43
+ export type SystemEffectMacOS = 'none' | 'pressed' | 'deepPressed' | 'disabled' | 'rollover';
44
+
45
+ /**
46
+ * A colour with one of AppKit's system effects applied. There is no iOS
47
+ * equivalent: UIKit expects the caller to supply the pressed or disabled
48
+ * colour, where AppKit derives it.
49
+ */
50
+ export const ColorWithSystemEffectMacOS = (
51
+ color: ColorValue,
52
+ effect: SystemEffectMacOS,
53
+ ): ColorValue => {
54
+ return ColorWithSystemEffectMacOSPrivate(color, effect);
55
+ };
@@ -1,23 +1,90 @@
1
- /*
1
+ /**
2
2
  * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @flow strict-local
7
+ * @flow strict
8
8
  * @format
9
9
  */
10
10
 
11
- // [macOS] macOS resolves as `.macos` -> `.native` -> shared, so without this
12
- // file `Platform` re-exports itself: the shared file is a
13
- // stub that expects a platform-suffixed sibling to answer. Point it at the iOS
14
- // implementation, which is what this fork uses on macOS wherever upstream has
15
- // no platform-neutral one. macOS]
11
+ // [macOS] The macOS implementation of Platform.
12
+ //
13
+ // `PlatformTypes.js` upstream already declares `'macos'` in `PlatformOSType`
14
+ // and a `MacOSPlatform` shape; only the module was missing, so `Platform.OS`
15
+ // came out as `'ios'` and every `Platform.select({macos: ...})` in the
16
+ // ecosystem silently took the iOS branch.
17
+ //
18
+ // The native constants come from the same `PlatformConstants` turbo module iOS
19
+ // uses -- the fork builds it for macOS and `RCTConstants.m` reports
20
+ // `RCTPlatformName` as `"macos"`. There is no interface idiom on macOS, so
21
+ // `isTV` and `isVision` are constants rather than reads. macOS]
16
22
 
17
- // NOTE: This file supports backwards compatibility of subpath (deep) imports
18
- // from 'react-native' with platform-specific extensions. It can be deleted
19
- // once we remove the "./*" mapping from package.json "exports".
23
+ import type {PlatformSelectSpec, PlatformType} from './PlatformTypes';
20
24
 
21
- import Platform from './Platform.ios';
25
+ import NativePlatformConstantsIOS from './NativePlatformConstantsIOS';
26
+
27
+ const Platform: PlatformType = {
28
+ __constants: null,
29
+ OS: 'macos',
30
+ // $FlowFixMe[unsafe-getters-setters]
31
+ get Version(): string {
32
+ // $FlowFixMe[object-this-reference]
33
+ return this.constants.osVersion;
34
+ },
35
+ // $FlowFixMe[unsafe-getters-setters]
36
+ get constants(): {
37
+ isTesting: boolean,
38
+ osVersion: string,
39
+ reactNativeVersion: {
40
+ major: number,
41
+ minor: number,
42
+ patch: number,
43
+ prerelease: ?number,
44
+ },
45
+ systemName: string,
46
+ } {
47
+ // $FlowFixMe[object-this-reference]
48
+ if (this.__constants == null) {
49
+ // $FlowFixMe[object-this-reference]
50
+ this.__constants = NativePlatformConstantsIOS.getConstants();
51
+ }
52
+ // $FlowFixMe[object-this-reference]
53
+ return this.__constants;
54
+ },
55
+ // $FlowFixMe[unsafe-getters-setters]
56
+ get isTV(): boolean {
57
+ return false;
58
+ },
59
+ // $FlowFixMe[unsafe-getters-setters]
60
+ get isVision(): boolean {
61
+ return false;
62
+ },
63
+ // $FlowFixMe[unsafe-getters-setters]
64
+ get isTesting(): boolean {
65
+ if (__DEV__) {
66
+ // $FlowFixMe[object-this-reference]
67
+ return this.constants.isTesting;
68
+ }
69
+ return false;
70
+ },
71
+ // $FlowFixMe[unsafe-getters-setters]
72
+ get isDisableAnimations(): boolean {
73
+ // $FlowFixMe[object-this-reference]
74
+ return this.constants.isDisableAnimations ?? this.isTesting;
75
+ },
76
+ // `macos` first, then `ios`, then `native`, then `default`. The iOS step
77
+ // matters: almost every `Platform.select` in the ecosystem predates macOS and
78
+ // only offers an `ios` branch, which is the right one to take here.
79
+ select: <T>(spec: PlatformSelectSpec<T>): T =>
80
+ // $FlowFixMe[incompatible-type]
81
+ 'macos' in spec
82
+ ? spec.macos
83
+ : 'ios' in spec
84
+ ? spec.ios
85
+ : 'native' in spec
86
+ ? spec.native
87
+ : spec.default,
88
+ };
22
89
 
23
90
  export default Platform;
@@ -850,6 +850,26 @@ static UIColor *RCTColorFromSemanticColorName(NSString *semanticColorName)
850
850
  NSDictionary<NSString *, NSDictionary *> *colorMap = RCTSemanticColorsMap();
851
851
  UIColor *color = nil;
852
852
  NSDictionary<NSString *, id> *colorInfo = colorMap[semanticColorName];
853
+
854
+ #if TARGET_OS_OSX // [macOS
855
+ // The map above is iOS's vocabulary. AppKit has its own -- labelColor,
856
+ // windowBackgroundColor, controlAccentColor and the rest -- and they are all
857
+ // class properties on NSColor, so asking NSColor directly covers every one of
858
+ // them without a second table to keep in sync. Only reached for names iOS
859
+ // does not define, so iOS names keep their mapping and their fallbacks.
860
+ if (colorInfo == nil) {
861
+ SEL appKitSelector = NSSelectorFromString(semanticColorName);
862
+ if (appKitSelector != nil && [UIColor respondsToSelector:appKitSelector]) {
863
+ IMP imp = [[UIColor class] methodForSelector:appKitSelector];
864
+ id (*getColor)(id, SEL) = (id (*)(id, SEL))imp;
865
+ id candidate = getColor([UIColor class], appKitSelector);
866
+ if ([candidate isKindOfClass:[UIColor class]]) {
867
+ return candidate;
868
+ }
869
+ }
870
+ }
871
+ #endif // macOS]
872
+
853
873
  if (colorInfo) {
854
874
  NSString *semanticColorSelector = colorInfo[RCTSelector];
855
875
  if (semanticColorSelector == nil) {
@@ -1040,6 +1060,35 @@ void RCTSetDefaultColorSpace(RCTColorSpace colorSpace)
1040
1060
  RCTLogConvertError(json, @"a UIColor. Expected an iOS dynamic appearance aware color.");
1041
1061
  return nil;
1042
1062
  }
1063
+ #if TARGET_OS_OSX // [macOS
1064
+ } else if ((value = [dictionary objectForKey:@"colorWithSystemEffect"])) {
1065
+ // AppKit's pressed / disabled / rollover variants of a colour. There is
1066
+ // no UIKit equivalent, so this arm exists only on macOS.
1067
+ NSDictionary *spec = value;
1068
+ UIColor *baseColor = [RCTConvert UIColor:[spec objectForKey:@"baseColor"]];
1069
+ NSString *effect = [RCTConvert NSString:[spec objectForKey:@"systemEffect"]];
1070
+ if (baseColor == nil) {
1071
+ RCTLogConvertError(json, @"a UIColor. colorWithSystemEffect needs a baseColor.");
1072
+ return nil;
1073
+ }
1074
+ static NSDictionary<NSString *, NSNumber *> *effects;
1075
+ static dispatch_once_t onceToken;
1076
+ dispatch_once(&onceToken, ^{
1077
+ effects = @{
1078
+ @"none" : @(NSColorSystemEffectNone),
1079
+ @"pressed" : @(NSColorSystemEffectPressed),
1080
+ @"deepPressed" : @(NSColorSystemEffectDeepPressed),
1081
+ @"disabled" : @(NSColorSystemEffectDisabled),
1082
+ @"rollover" : @(NSColorSystemEffectRollover),
1083
+ };
1084
+ });
1085
+ NSNumber *resolved = effects[effect ?: @"none"];
1086
+ if (resolved == nil) {
1087
+ RCTLogConvertError(json, @"a UIColor. Unknown system effect.");
1088
+ return nil;
1089
+ }
1090
+ return [baseColor colorWithSystemEffect:(NSColorSystemEffect)resolved.integerValue];
1091
+ #endif // macOS]
1043
1092
  } else {
1044
1093
  RCTLogConvertError(json, @"a UIColor. Expected an iOS semantic color or dynamic appearance aware color.");
1045
1094
  return nil;