@fluentui-react-native/callout 0.29.6 → 0.29.7

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 (66) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +18 -0
  3. package/lib/index.d.ts +2 -3
  4. package/lib/index.d.ts.map +1 -1
  5. package/lib/index.js +1 -2
  6. package/lib/index.js.map +1 -1
  7. package/package.json +12 -27
  8. package/src/index.ts +2 -3
  9. package/.cache/tsconfig.tsbuildinfo +0 -1
  10. package/FRNCallout.podspec +0 -24
  11. package/NuGet.config +0 -10
  12. package/SPEC.md +0 -46
  13. package/jest.config.cjs +0 -1
  14. package/lib/Callout.d.ts +0 -6
  15. package/lib/Callout.d.ts.map +0 -1
  16. package/lib/Callout.js +0 -64
  17. package/lib/Callout.js.map +0 -1
  18. package/lib/Callout.types.d.ts +0 -85
  19. package/lib/Callout.types.d.ts.map +0 -1
  20. package/lib/Callout.types.js +0 -2
  21. package/lib/Callout.types.js.map +0 -1
  22. package/lib/CalloutNativeComponent.d.ts +0 -49
  23. package/lib/CalloutNativeComponent.d.ts.map +0 -1
  24. package/lib/CalloutNativeComponent.js +0 -9
  25. package/lib/CalloutNativeComponent.js.map +0 -1
  26. package/lib/__tests__/Callout.test.d.ts +0 -2
  27. package/lib/__tests__/Callout.test.d.ts.map +0 -1
  28. package/lib/__tests__/Callout.test.js +0 -96
  29. package/lib/__tests__/Callout.test.js.map +0 -1
  30. package/lib/__tests__/Callout.types.test.d.ts +0 -2
  31. package/lib/__tests__/Callout.types.test.d.ts.map +0 -1
  32. package/lib/__tests__/Callout.types.test.js +0 -21
  33. package/lib/__tests__/Callout.types.test.js.map +0 -1
  34. package/macos/CalloutManager.swift +0 -16
  35. package/macos/CalloutView.swift +0 -454
  36. package/macos/CalloutWindow.swift +0 -40
  37. package/macos/FRNCallout.h +0 -14
  38. package/macos/FRNCalloutManager.h +0 -5
  39. package/macos/FRNCalloutManager.m +0 -76
  40. package/macos/FlippedVisualEffectView.swift +0 -10
  41. package/macos/GuardedEventMonitor.swift +0 -28
  42. package/macos/RCTCalloutComponentView.h +0 -12
  43. package/macos/RCTCalloutComponentView.mm +0 -209
  44. package/react-native.config.cjs +0 -15
  45. package/src/Callout.stories.tsx +0 -276
  46. package/src/Callout.tsx +0 -111
  47. package/src/Callout.types.ts +0 -106
  48. package/src/CalloutNativeComponent.ts +0 -74
  49. package/src/__tests__/Callout.test.tsx +0 -157
  50. package/src/__tests__/Callout.types.test.ts +0 -30
  51. package/src/__tests__/__snapshots__/Callout.test.tsx.snap +0 -11
  52. package/tsconfig.json +0 -19
  53. package/windows/Callout/Callout.cpp +0 -420
  54. package/windows/Callout/Callout.def +0 -3
  55. package/windows/Callout/Callout.h +0 -25
  56. package/windows/Callout/Callout.vcxproj +0 -152
  57. package/windows/Callout/ReactPackageProvider.cpp +0 -25
  58. package/windows/Callout/ReactPackageProvider.h +0 -25
  59. package/windows/Callout/ReactPackageProvider.idl +0 -12
  60. package/windows/Callout/codegen/.clang-format +0 -2
  61. package/windows/Callout/codegen/react/components/FRNCalloutSpec/Callout.g.h +0 -375
  62. package/windows/Callout/packages.lock.json +0 -151
  63. package/windows/Callout/pch.cpp +0 -1
  64. package/windows/Callout/pch.h +0 -28
  65. package/windows/ExperimentalFeatures.props +0 -33
  66. package/windows/NuGet.Config +0 -13
@@ -1,209 +0,0 @@
1
- #ifdef RCT_NEW_ARCH_ENABLED
2
-
3
- #import "RCTCalloutComponentView.h"
4
-
5
- #import <react/renderer/components/FRNCalloutSpec/ComponentDescriptors.h>
6
- #import <react/renderer/components/FRNCalloutSpec/EventEmitters.h>
7
- #import <react/renderer/components/FRNCalloutSpec/Props.h>
8
- #import <react/renderer/components/FRNCalloutSpec/RCTComponentViewHelpers.h>
9
-
10
- #import <React/RCTComponent.h>
11
- #import <React/RCTComponentViewProtocol.h>
12
- #import <React/RCTConversions.h>
13
- #import <React/RCTSurfaceTouchHandler.h>
14
- #import <React/RCTView.h>
15
-
16
- #import "FRNCallout-Swift.h"
17
-
18
- using namespace facebook::react;
19
-
20
- static NSRectEdge RCTNSRectEdgeFromDirectionalHint(CalloutDirectionalHint hint)
21
- {
22
- // CalloutView uses MinY for placement above the anchor and MaxY for placement below it.
23
- switch (hint) {
24
- case CalloutDirectionalHint::LeftTopEdge:
25
- case CalloutDirectionalHint::LeftCenter:
26
- case CalloutDirectionalHint::LeftBottomEdge:
27
- return NSRectEdgeMinX;
28
- case CalloutDirectionalHint::TopLeftEdge:
29
- case CalloutDirectionalHint::TopAutoEdge:
30
- case CalloutDirectionalHint::TopCenter:
31
- case CalloutDirectionalHint::TopRightEdge:
32
- return NSRectEdgeMinY;
33
- case CalloutDirectionalHint::RightTopEdge:
34
- case CalloutDirectionalHint::RightCenter:
35
- case CalloutDirectionalHint::RightBottomEdge:
36
- return NSRectEdgeMaxX;
37
- case CalloutDirectionalHint::BottomLeftEdge:
38
- case CalloutDirectionalHint::BottomAutoEdge:
39
- case CalloutDirectionalHint::BottomCenter:
40
- case CalloutDirectionalHint::BottomRightEdge:
41
- return NSRectEdgeMaxY;
42
- }
43
- }
44
-
45
- static void RCTApplyCalloutAppearance(
46
- FRNCalloutView *calloutView,
47
- const CalloutProps &props,
48
- const LayoutMetrics &layoutMetrics)
49
- {
50
- const auto borderMetrics = props.resolveBorderMetrics(layoutMetrics);
51
- calloutView.backgroundColor = RCTUIColorFromSharedColor(props.backgroundColor) ?: NSColor.clearColor;
52
- calloutView.borderColor = RCTUIColorFromSharedColor(borderMetrics.borderColors.left) ?: NSColor.clearColor;
53
- calloutView.borderWidth = borderMetrics.borderWidths.left;
54
- calloutView.borderRadius = borderMetrics.borderRadii.topLeft.horizontal;
55
- [calloutView setNeedsDisplay:YES];
56
- }
57
-
58
- static RCTPlatformView *RCTFindComponentViewWithTag(RCTPlatformView *rootView, NSInteger tag)
59
- {
60
- if ([rootView conformsToProtocol:@protocol(RCTComponentViewProtocol)] &&
61
- [((id<RCTComponentViewProtocol>)rootView).reactTag integerValue] == tag) {
62
- return rootView;
63
- }
64
-
65
- for (RCTPlatformView *subview in rootView.subviews) {
66
- RCTPlatformView *match = RCTFindComponentViewWithTag(subview, tag);
67
- if (match) {
68
- return match;
69
- }
70
- }
71
-
72
- return nil;
73
- }
74
-
75
- @interface RCTCalloutComponentView () <RCTCalloutViewProtocol>
76
- @end
77
-
78
- @implementation RCTCalloutComponentView {
79
- FRNCalloutView *_calloutView;
80
- NSInteger _targetTag;
81
- RCTSurfaceTouchHandler *_touchHandler;
82
- }
83
-
84
- + (ComponentDescriptorProvider)componentDescriptorProvider
85
- {
86
- // Fabric normalizes the legacy RCT-prefixed view name before component lookup.
87
- return concreteComponentDescriptorProvider<CalloutComponentDescriptor>();
88
- }
89
-
90
- - (instancetype)initWithFrame:(CGRect)frame
91
- {
92
- if (self = [super initWithFrame:frame]) {
93
- static const auto defaultProps = std::make_shared<const CalloutProps>();
94
- _props = defaultProps;
95
-
96
- // This view manages content mounted in the Callout window and must not render in the React surface.
97
- self.hidden = YES;
98
-
99
- _calloutView = [[FRNCalloutView alloc] initWithFrame:self.bounds];
100
-
101
- __weak RCTCalloutComponentView *weakSelf = self;
102
- _calloutView.onShow = ^(__unused NSDictionary *event) {
103
- [weakSelf emitOnShow];
104
- };
105
- _calloutView.onDismiss = ^(__unused NSDictionary *event) {
106
- [weakSelf emitOnDismiss];
107
- };
108
-
109
- _touchHandler = [RCTSurfaceTouchHandler new];
110
- [_touchHandler attachToView:_calloutView.contentProxyView];
111
-
112
- self.contentView = _calloutView;
113
- }
114
- return self;
115
- }
116
-
117
- - (void)mountChildComponentView:(RCTUIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
118
- {
119
- [_calloutView mountContentSubview:childComponentView at:index];
120
- }
121
-
122
- - (void)unmountChildComponentView:(RCTUIView<RCTComponentViewProtocol> *)childComponentView index:(__unused NSInteger)index
123
- {
124
- [_calloutView unmountContentSubview:childComponentView];
125
- }
126
-
127
- - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
128
- {
129
- const auto &newProps = *std::static_pointer_cast<const CalloutProps>(props);
130
-
131
- _calloutView.directionalHint = RCTNSRectEdgeFromDirectionalHint(newProps.directionalHint);
132
- _calloutView.setInitialFocus = newProps.setInitialFocus;
133
-
134
- const auto &rect = newProps.anchorRect;
135
- _calloutView.anchorRect = NSMakeRect(rect.screenX, rect.screenY, rect.width, rect.height);
136
-
137
- _targetTag = 0;
138
- if (newProps.target.isNumber()) {
139
- _targetTag = (NSInteger)newProps.target.asDouble();
140
- }
141
- [self updateAnchorView];
142
- RCTApplyCalloutAppearance(_calloutView, newProps, _layoutMetrics);
143
-
144
- [super updateProps:props oldProps:oldProps];
145
- }
146
-
147
- - (void)viewDidMoveToWindow
148
- {
149
- [super viewDidMoveToWindow];
150
- [self updateAnchorView];
151
- }
152
-
153
- - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
154
- oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics
155
- {
156
- [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
157
-
158
- const auto size = layoutMetrics.frame.size;
159
- [_calloutView updateContentSize:NSMakeSize(size.width, size.height)];
160
-
161
- const auto &props = *std::static_pointer_cast<const CalloutProps>(_props);
162
- RCTApplyCalloutAppearance(_calloutView, props, layoutMetrics);
163
- }
164
-
165
- - (void)prepareForRecycle
166
- {
167
- [super prepareForRecycle];
168
- _targetTag = 0;
169
- [_calloutView setAnchorView:nil];
170
- }
171
-
172
- - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
173
- {
174
- RCTCalloutHandleCommand(self, commandName, args);
175
- }
176
-
177
- - (void)focusWindow
178
- {
179
- [_calloutView focusWindow];
180
- }
181
-
182
- - (void)blurWindow
183
- {
184
- [_calloutView blurWindow];
185
- }
186
-
187
- - (void)updateAnchorView
188
- {
189
- RCTPlatformView *rootView = self.window.contentView;
190
- [_calloutView setAnchorView:_targetTag > 0 && rootView ? RCTFindComponentViewWithTag(rootView, _targetTag) : nil];
191
- }
192
-
193
- - (void)emitOnShow
194
- {
195
- if (_eventEmitter) {
196
- std::static_pointer_cast<const CalloutEventEmitter>(_eventEmitter)->onShow({.target = 0});
197
- }
198
- }
199
-
200
- - (void)emitOnDismiss
201
- {
202
- if (_eventEmitter) {
203
- std::static_pointer_cast<const CalloutEventEmitter>(_eventEmitter)->onDismiss({.target = 0});
204
- }
205
- }
206
-
207
- @end
208
-
209
- #endif
@@ -1,15 +0,0 @@
1
- module.exports = {
2
- dependency: {
3
- platforms: {
4
- windows: {
5
- sourceDir: 'windows',
6
- projects: [
7
- {
8
- projectFile: 'Callout/Callout.vcxproj',
9
- directDependency: true,
10
- },
11
- ],
12
- },
13
- },
14
- },
15
- };
@@ -1,276 +0,0 @@
1
- /** @jsxImportSource @fluentui-react-native/framework-base */
2
- import * as React from 'react';
3
- import { Pressable, StyleSheet, Text, View } from 'react-native';
4
-
5
- import type { Meta, StoryObj } from '@storybook/react-native';
6
-
7
- import { Callout } from './Callout';
8
- import type { CalloutHandle, CalloutProps, DirectionalHint } from './Callout.types';
9
-
10
- const directionalHints: readonly DirectionalHint[] = [
11
- 'leftTopEdge',
12
- 'leftCenter',
13
- 'leftBottomEdge',
14
- 'topLeftEdge',
15
- 'topAutoEdge',
16
- 'topCenter',
17
- 'topRightEdge',
18
- 'rightTopEdge',
19
- 'rightCenter',
20
- 'rightBottomEdge',
21
- 'bottomLeftEdge',
22
- 'bottomAutoEdge',
23
- 'bottomCenter',
24
- 'bottomRightEdge',
25
- ];
26
-
27
- type CalloutExampleProps = CalloutProps & {
28
- defaultVisible?: boolean;
29
- showWindowCommands?: boolean;
30
- };
31
-
32
- const CalloutExample = ({ defaultVisible = false, onDismiss, onShow, showWindowCommands = false, ...props }: CalloutExampleProps) => {
33
- const anchorRef = React.useRef<View>(null);
34
- const calloutRef = React.useRef<CalloutHandle>(null);
35
- const [visible, setVisible] = React.useState(defaultVisible);
36
- const [status, setStatus] = React.useState(defaultVisible ? 'Opening' : 'Closed');
37
-
38
- const dismiss = React.useCallback(() => {
39
- setVisible(false);
40
- setStatus('Dismissed');
41
- onDismiss?.();
42
- }, [onDismiss]);
43
-
44
- const show = React.useCallback(() => {
45
- setStatus('Shown');
46
- onShow?.();
47
- }, [onShow]);
48
-
49
- return (
50
- <View style={styles.story}>
51
- <View>
52
- <Pressable
53
- accessibilityRole="button"
54
- onPress={() => {
55
- setVisible((current) => !current);
56
- setStatus(visible ? 'Closed' : 'Opening');
57
- }}
58
- ref={anchorRef}
59
- style={({ pressed }) => [styles.trigger, pressed && styles.triggerPressed]}
60
- testID="agentic-storybook-callout-trigger"
61
- >
62
- <Text style={styles.triggerText}>{visible ? 'Close callout' : 'Open callout'}</Text>
63
- </Pressable>
64
- </View>
65
- <Text accessibilityLiveRegion="polite" style={styles.status} testID="agentic-storybook-callout-status">
66
- Native window: {status}
67
- </Text>
68
- {visible && (
69
- <Callout {...props} componentRef={calloutRef} onDismiss={dismiss} onShow={show} target={anchorRef}>
70
- <View style={styles.calloutContent} collapsable={false}>
71
- <Text style={styles.heading}>Fabric Callout</Text>
72
- <Text style={styles.body}>This content is hosted in a separate native window.</Text>
73
- {showWindowCommands && (
74
- <View style={styles.commandRow}>
75
- <Pressable accessibilityRole="button" onPress={() => calloutRef.current?.focusWindow()} style={styles.command}>
76
- <Text>Focus window</Text>
77
- </Pressable>
78
- <Pressable accessibilityRole="button" onPress={() => calloutRef.current?.blurWindow()} style={styles.command}>
79
- <Text>Blur window</Text>
80
- </Pressable>
81
- </View>
82
- )}
83
- </View>
84
- </Callout>
85
- )}
86
- </View>
87
- );
88
- };
89
-
90
- type Placement = {
91
- hint: DirectionalHint;
92
- label: string;
93
- };
94
-
95
- const placements: readonly Placement[] = [
96
- { hint: 'topCenter', label: 'Above' },
97
- { hint: 'rightCenter', label: 'Right' },
98
- { hint: 'bottomCenter', label: 'Below' },
99
- { hint: 'leftCenter', label: 'Left' },
100
- ];
101
-
102
- const PlacementExample = (props: CalloutProps) => {
103
- const aboveRef = React.useRef<View>(null);
104
- const rightRef = React.useRef<View>(null);
105
- const belowRef = React.useRef<View>(null);
106
- const leftRef = React.useRef<View>(null);
107
- const targetRefs = [aboveRef, rightRef, belowRef, leftRef] as const;
108
- const [selectedIndex, setSelectedIndex] = React.useState<number>();
109
-
110
- return (
111
- <View style={styles.placementStory}>
112
- {placements.map(({ hint, label }, index) => (
113
- <View key={hint} style={styles.placementAnchor}>
114
- <Pressable
115
- accessibilityRole="button"
116
- onPress={() => setSelectedIndex(index)}
117
- ref={targetRefs[index]}
118
- style={({ pressed }) => [styles.trigger, pressed && styles.triggerPressed]}
119
- testID={`agentic-storybook-callout-placement-${hint}-trigger`}
120
- >
121
- <Text style={styles.triggerText}>{label}</Text>
122
- </Pressable>
123
- </View>
124
- ))}
125
- {selectedIndex !== undefined && (
126
- <Callout
127
- {...props}
128
- directionalHint={placements[selectedIndex].hint}
129
- onDismiss={() => setSelectedIndex(undefined)}
130
- target={targetRefs[selectedIndex]}
131
- >
132
- <View accessible style={styles.calloutContent} collapsable={false} testID="agentic-storybook-callout-placement-content">
133
- <Text style={styles.heading}>{placements[selectedIndex].label}</Text>
134
- <Text style={styles.body}>Click outside the native window to dismiss it.</Text>
135
- </View>
136
- </Callout>
137
- )}
138
- </View>
139
- );
140
- };
141
-
142
- const meta: Meta<typeof Callout> = {
143
- title: 'Native/Callout',
144
- component: Callout,
145
- args: {
146
- accessibilityLabel: 'Callout example',
147
- accessibilityRole: 'dialog',
148
- backgroundColor: '#ffffff',
149
- borderColor: '#d1d1d1',
150
- borderRadius: 8,
151
- borderWidth: 1,
152
- directionalHint: 'bottomCenter',
153
- maxWidth: 320,
154
- setInitialFocus: false,
155
- testID: 'agentic-storybook-callout',
156
- },
157
- argTypes: {
158
- backgroundColor: { control: 'color' },
159
- borderColor: { control: 'color' },
160
- borderRadius: { control: { type: 'number', min: 0, max: 24, step: 1 } },
161
- borderWidth: { control: { type: 'number', min: 0, max: 8, step: 1 } },
162
- directionalHint: { control: 'select', options: directionalHints },
163
- maxHeight: { control: { type: 'number', min: 80, max: 600, step: 20 } },
164
- maxWidth: { control: { type: 'number', min: 120, max: 600, step: 20 } },
165
- minWidth: { control: { type: 'number', min: 80, max: 400, step: 20 } },
166
- setInitialFocus: { control: 'boolean' },
167
- },
168
- parameters: {
169
- docs: {
170
- description: {
171
- component:
172
- 'Callout is an unstyled native primitive that presents React content in a transient window positioned relative to a target.',
173
- },
174
- },
175
- },
176
- };
177
-
178
- export default meta;
179
-
180
- type Story = StoryObj<typeof Callout>;
181
-
182
- export const Default: Story = {
183
- render: (args) => <CalloutExample {...args} defaultVisible />,
184
- };
185
-
186
- export const Placement: Story = {
187
- render: (args) => <PlacementExample {...args} />,
188
- parameters: {
189
- docs: {
190
- description: {
191
- story: 'Each trigger requests one of four placement edges. The native Callout remains within the available work area.',
192
- },
193
- },
194
- },
195
- };
196
-
197
- export const WindowCommands: Story = {
198
- args: {
199
- setInitialFocus: true,
200
- },
201
- render: (args) => <CalloutExample {...args} defaultVisible showWindowCommands />,
202
- parameters: {
203
- docs: {
204
- description: {
205
- story: 'The content buttons exercise Fabric touch handling and the imperative focusWindow and blurWindow native commands.',
206
- },
207
- },
208
- },
209
- };
210
-
211
- const styles = StyleSheet.create({
212
- body: {
213
- color: '#424242',
214
- marginTop: 6,
215
- },
216
- calloutContent: {
217
- backgroundColor: '#ffffff',
218
- borderColor: '#d1d1d1',
219
- borderRadius: 8,
220
- borderWidth: 1,
221
- padding: 16,
222
- width: 280,
223
- },
224
- command: {
225
- backgroundColor: '#f5f5f5',
226
- borderColor: '#d1d1d1',
227
- borderRadius: 4,
228
- borderWidth: 1,
229
- paddingHorizontal: 12,
230
- paddingVertical: 8,
231
- },
232
- commandRow: {
233
- flexDirection: 'row',
234
- gap: 8,
235
- marginTop: 16,
236
- },
237
- heading: {
238
- color: '#242424',
239
- fontSize: 16,
240
- fontWeight: '600',
241
- },
242
- placementAnchor: {
243
- margin: 32,
244
- },
245
- placementStory: {
246
- alignItems: 'center',
247
- flexDirection: 'row',
248
- flexWrap: 'wrap',
249
- justifyContent: 'center',
250
- minHeight: 300,
251
- width: 520,
252
- },
253
- status: {
254
- color: '#616161',
255
- marginTop: 12,
256
- },
257
- story: {
258
- alignItems: 'center',
259
- justifyContent: 'center',
260
- minHeight: 300,
261
- width: 520,
262
- },
263
- trigger: {
264
- backgroundColor: '#0f6cbd',
265
- borderRadius: 4,
266
- paddingHorizontal: 16,
267
- paddingVertical: 10,
268
- },
269
- triggerPressed: {
270
- backgroundColor: '#115ea3',
271
- },
272
- triggerText: {
273
- color: '#ffffff',
274
- fontWeight: '600',
275
- },
276
- });
package/src/Callout.tsx DELETED
@@ -1,111 +0,0 @@
1
- /** @jsxImportSource @fluentui-react-native/framework-base */
2
- import * as React from 'react';
3
- import { findNodeHandle, StyleSheet } from 'react-native';
4
-
5
- import { directComponent, mergeProps, phasedComponent } from '@fluentui-react-native/framework-base';
6
-
7
- import type { CalloutProps } from './Callout.types';
8
- import { calloutName } from './Callout.types';
9
- import NativeCalloutView, { Commands } from './CalloutNativeComponent';
10
-
11
- const colorTransparent = '#00000000';
12
-
13
- const styles = StyleSheet.create({
14
- root: {
15
- position: 'absolute',
16
- },
17
- });
18
-
19
- /**
20
- * Renders the native Callout without applying theme or appearance defaults.
21
- */
22
- export const Callout = phasedComponent<CalloutProps>((props) => {
23
- const { componentRef, target } = props;
24
- const nativeComponentRef = React.useRef<React.ElementRef<typeof NativeCalloutView> | null>(null);
25
- const [nativeTarget, setNativeTarget] = React.useState<number | string | undefined>(undefined);
26
-
27
- React.useImperativeHandle(
28
- componentRef,
29
- () => ({
30
- blurWindow() {
31
- if (nativeComponentRef.current !== null) {
32
- Commands.blurWindow(nativeComponentRef.current);
33
- }
34
- },
35
- focusWindow() {
36
- if (nativeComponentRef.current !== null) {
37
- Commands.focusWindow(nativeComponentRef.current);
38
- }
39
- },
40
- }),
41
- [],
42
- );
43
-
44
- React.useLayoutEffect(() => {
45
- if (typeof target === 'string') {
46
- setNativeTarget(target);
47
- } else if (target?.current) {
48
- setNativeTarget(findNodeHandle(target.current) ?? undefined);
49
- } else {
50
- setNativeTarget(undefined);
51
- }
52
- }, [target]);
53
-
54
- return directComponent<CalloutProps>((renderProps) => {
55
- const {
56
- anchorRect,
57
- backgroundColor,
58
- beakWidth,
59
- borderColor,
60
- borderRadius,
61
- borderWidth,
62
- componentRef: _componentRef,
63
- directionalHint,
64
- dismissBehaviors,
65
- gapSpace,
66
- maxHeight,
67
- maxWidth,
68
- minPadding,
69
- minWidth,
70
- style,
71
- target: _target,
72
- ...nativeProps
73
- } = mergeProps(props, renderProps);
74
-
75
- /**
76
- * Build the style for the callout based on the props. For `borderColor`, `borderWidth`, `backgroundColor`, and
77
- * `borderRadius` defaults values are required otherwise crashes in CalloutView.swift:updateLayer() will occur.
78
- */
79
- const calloutStyle = {
80
- backgroundColor: backgroundColor ?? colorTransparent,
81
- borderColor: borderColor ?? colorTransparent,
82
- borderWidth: borderWidth ?? 0,
83
- borderRadius: borderRadius ?? 0,
84
- ...(maxHeight != null && { maxHeight }),
85
- ...(maxWidth != null && { maxWidth }),
86
- ...(minWidth != null && { minWidth }),
87
- };
88
-
89
- return (
90
- <NativeCalloutView
91
- {...nativeProps}
92
- anchorRect={anchorRect}
93
- beakWidth={beakWidth}
94
- directionalHint={directionalHint}
95
- dismissBehaviors={dismissBehaviors}
96
- gapSpace={gapSpace}
97
- maxHeight={typeof maxHeight === 'number' ? maxHeight : undefined}
98
- maxWidth={typeof maxWidth === 'number' ? maxWidth : undefined}
99
- minPadding={minPadding}
100
- minWidth={typeof minWidth === 'number' ? minWidth : undefined}
101
- ref={nativeComponentRef}
102
- style={[styles.root, calloutStyle, style]}
103
- {...(nativeTarget !== undefined && { target: nativeTarget })}
104
- />
105
- );
106
- });
107
- });
108
-
109
- Callout.displayName = calloutName;
110
-
111
- export default Callout;