@fluentui-react-native/tester 0.59.38 → 0.60.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/CHANGELOG.json +76 -1
- package/CHANGELOG.md +31 -2
- package/lib/FluentTester/TestComponents/Avatar/BasicAvatar.d.ts.map +1 -1
- package/lib/FluentTester/TestComponents/Avatar/BasicAvatar.js +3 -2
- package/lib/FluentTester/TestComponents/Avatar/BasicAvatar.js.map +1 -1
- package/lib/FluentTester/TestComponents/Avatar/CustomizedAvatar.d.ts.map +1 -1
- package/lib/FluentTester/TestComponents/Avatar/CustomizedAvatar.js +9 -14
- package/lib/FluentTester/TestComponents/Avatar/CustomizedAvatar.js.map +1 -1
- package/lib/FluentTester/TestComponents/Callout/CalloutTest.d.ts.map +1 -1
- package/lib/FluentTester/TestComponents/Callout/CalloutTest.js +98 -37
- package/lib/FluentTester/TestComponents/Callout/CalloutTest.js.map +1 -1
- package/lib-commonjs/FluentTester/TestComponents/Avatar/BasicAvatar.d.ts.map +1 -1
- package/lib-commonjs/FluentTester/TestComponents/Avatar/BasicAvatar.js +3 -2
- package/lib-commonjs/FluentTester/TestComponents/Avatar/BasicAvatar.js.map +1 -1
- package/lib-commonjs/FluentTester/TestComponents/Avatar/CustomizedAvatar.d.ts.map +1 -1
- package/lib-commonjs/FluentTester/TestComponents/Avatar/CustomizedAvatar.js +9 -14
- package/lib-commonjs/FluentTester/TestComponents/Avatar/CustomizedAvatar.js.map +1 -1
- package/lib-commonjs/FluentTester/TestComponents/Callout/CalloutTest.d.ts.map +1 -1
- package/lib-commonjs/FluentTester/TestComponents/Callout/CalloutTest.js +97 -36
- package/lib-commonjs/FluentTester/TestComponents/Callout/CalloutTest.js.map +1 -1
- package/package.json +5 -5
- package/src/FluentTester/TestComponents/Avatar/BasicAvatar.tsx +3 -2
- package/src/FluentTester/TestComponents/Avatar/CustomizedAvatar.tsx +10 -15
- package/src/FluentTester/TestComponents/Callout/CalloutTest.tsx +138 -32
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ScreenRect, Text, View, Switch, Picker, ScrollView } from 'react-native';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Callout,
|
|
6
|
+
Separator,
|
|
7
|
+
IFocusable,
|
|
8
|
+
Pressable,
|
|
9
|
+
RestoreFocusEvent,
|
|
10
|
+
DismissBehaviors,
|
|
11
|
+
StealthButton,
|
|
12
|
+
} from '@fluentui/react-native';
|
|
4
13
|
import { CALLOUT_TESTPAGE } from './consts';
|
|
5
14
|
import { Test, TestSection, PlatformStatus } from '../Test';
|
|
6
15
|
import { E2ECalloutTest } from './CalloutE2ETest';
|
|
@@ -9,6 +18,8 @@ import { fluentTesterStyles } from '../Common/styles';
|
|
|
9
18
|
const StandardCallout: React.FunctionComponent = () => {
|
|
10
19
|
const [showStandardCallout, setShowStandardCallout] = React.useState(false);
|
|
11
20
|
const [isStandardCalloutVisible, setIsStandardCalloutVisible] = React.useState(false);
|
|
21
|
+
const [openCalloutOnHoverAnchor, setOpenCalloutOnHoverAnchor] = React.useState(true);
|
|
22
|
+
const [calloutHovered, setCalloutHovered] = React.useState(false);
|
|
12
23
|
|
|
13
24
|
const [shouldSetInitialFocus, setShouldSetInitialFocus] = React.useState(true);
|
|
14
25
|
const onInitialFocusChange = React.useCallback((value) => setShouldSetInitialFocus(value), []);
|
|
@@ -59,32 +70,94 @@ const StandardCallout: React.FunctionComponent = () => {
|
|
|
59
70
|
const decoyBtn1Ref = React.useRef<IFocusable>(null);
|
|
60
71
|
const decoyBtn2Ref = React.useRef<IFocusable>(null);
|
|
61
72
|
const [anchorRef, setAnchorRef] = React.useState(redTargetRef);
|
|
73
|
+
const [hoveredTargetsCount, setHoveredTargetsCount] = React.useState(0);
|
|
74
|
+
const [displayCountHoveredTargets, setDisplayCountHoveredTargets] = React.useState(0);
|
|
75
|
+
|
|
76
|
+
const anchorRefsInfo: { hoverCount: number; isCurrentAnchor: boolean[] } = React.useMemo(() => {
|
|
77
|
+
return {
|
|
78
|
+
hoverCount: displayCountHoveredTargets,
|
|
79
|
+
isCurrentAnchor: [
|
|
80
|
+
openCalloutOnHoverAnchor && isStandardCalloutVisible && anchorRef == redTargetRef,
|
|
81
|
+
openCalloutOnHoverAnchor && isStandardCalloutVisible && anchorRef == greenTargetRef,
|
|
82
|
+
openCalloutOnHoverAnchor && isStandardCalloutVisible && anchorRef == blueTargetRef,
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}, [anchorRef, displayCountHoveredTargets, isStandardCalloutVisible, openCalloutOnHoverAnchor]);
|
|
86
|
+
|
|
87
|
+
// Use a timer to update the targets count and avoid jittery updates of counts on-screen
|
|
88
|
+
React.useLayoutEffect(() => {
|
|
89
|
+
const timer = setTimeout(() => {
|
|
90
|
+
setDisplayCountHoveredTargets(hoveredTargetsCount);
|
|
91
|
+
}, 50);
|
|
92
|
+
|
|
93
|
+
return () => clearTimeout(timer);
|
|
94
|
+
}, [hoveredTargetsCount]);
|
|
95
|
+
|
|
96
|
+
React.useLayoutEffect(() => {
|
|
97
|
+
// The callout may be dismissed by multiple mechanisms, depending on its active invocation
|
|
98
|
+
// mechanisms. In each of those dismissal routes, we use this function to reset the callout's
|
|
99
|
+
// state universally.
|
|
100
|
+
if (!showStandardCallout) {
|
|
101
|
+
setIsStandardCalloutVisible(false);
|
|
102
|
+
setCalloutHovered(false);
|
|
103
|
+
}
|
|
104
|
+
}, [showStandardCallout]);
|
|
62
105
|
|
|
63
106
|
const toggleShowStandardCallout = React.useCallback(() => {
|
|
64
107
|
setShowStandardCallout(!showStandardCallout);
|
|
108
|
+
}, [showStandardCallout]);
|
|
109
|
+
|
|
110
|
+
// Set up a LayoutEffect for hover callout mechanics including:
|
|
111
|
+
// the toggle switch for hover callout behavior
|
|
112
|
+
// multiple hover targets (i.e. the callout and its anchor)
|
|
113
|
+
// a dismissal timer for closing the callout with no targets hovered
|
|
114
|
+
React.useLayoutEffect(() => {
|
|
115
|
+
if (!openCalloutOnHoverAnchor) {
|
|
116
|
+
setShowStandardCallout(false);
|
|
117
|
+
} else if (openCalloutOnHoverAnchor && hoveredTargetsCount > 0) {
|
|
118
|
+
setShowStandardCallout(true);
|
|
119
|
+
} else {
|
|
120
|
+
const timer = setTimeout(() => {
|
|
121
|
+
setShowStandardCallout(false);
|
|
122
|
+
}, 2000);
|
|
123
|
+
return () => clearTimeout(timer);
|
|
124
|
+
}
|
|
125
|
+
return undefined;
|
|
126
|
+
}, [openCalloutOnHoverAnchor, hoveredTargetsCount]);
|
|
127
|
+
|
|
128
|
+
const updateCalloutTargetsHoverState = React.useCallback(
|
|
129
|
+
(show: boolean, hoverAnchorRef: React.MutableRefObject<View>) => {
|
|
130
|
+
if (hoverAnchorRef !== undefined && hoverAnchorRef !== anchorRef) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
65
133
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
134
|
+
setHoveredTargetsCount(hoveredTargetsCount + (show ? 1 : -1));
|
|
135
|
+
},
|
|
136
|
+
[anchorRef, hoveredTargetsCount, setHoveredTargetsCount],
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const calloutHoveredCallback = React.useCallback(
|
|
140
|
+
(isHovered: boolean) => {
|
|
141
|
+
updateCalloutTargetsHoverState(isHovered, undefined);
|
|
142
|
+
setCalloutHovered(isHovered);
|
|
143
|
+
},
|
|
144
|
+
[updateCalloutTargetsHoverState],
|
|
145
|
+
);
|
|
71
146
|
|
|
72
147
|
const toggleCalloutRef = React.useCallback(() => {
|
|
73
148
|
// Cycle the target ref between the RGB target views
|
|
74
149
|
setAnchorRef(anchorRef === redTargetRef ? greenTargetRef : anchorRef === greenTargetRef ? blueTargetRef : redTargetRef);
|
|
75
|
-
}, [anchorRef
|
|
150
|
+
}, [anchorRef]);
|
|
76
151
|
|
|
77
152
|
const onShowStandardCallout = React.useCallback(() => {
|
|
78
153
|
setIsStandardCalloutVisible(true);
|
|
79
|
-
}, [
|
|
154
|
+
}, []);
|
|
80
155
|
|
|
81
156
|
const onDismissStandardCallout = React.useCallback(() => {
|
|
82
|
-
setIsStandardCalloutVisible(false);
|
|
83
|
-
|
|
84
157
|
// setting the internal state to false will instigate unmounting the
|
|
85
158
|
// zombie Callout control.
|
|
86
159
|
setShowStandardCallout(false);
|
|
87
|
-
}, [
|
|
160
|
+
}, []);
|
|
88
161
|
|
|
89
162
|
const onRestoreFocusStandardCallout = React.useCallback(
|
|
90
163
|
(restoreFocusEvent: RestoreFocusEvent) => {
|
|
@@ -125,6 +198,11 @@ const StandardCallout: React.FunctionComponent = () => {
|
|
|
125
198
|
<View>
|
|
126
199
|
<View style={{ flexDirection: 'row', paddingVertical: 5 }}>
|
|
127
200
|
<View style={{ flexDirection: 'column', paddingHorizontal: 5 }}>
|
|
201
|
+
<View style={{ flexDirection: 'row' }}>
|
|
202
|
+
<Switch value={openCalloutOnHoverAnchor} onValueChange={setOpenCalloutOnHoverAnchor} />
|
|
203
|
+
<Text>Show Callout On Hover Anchor</Text>
|
|
204
|
+
</View>
|
|
205
|
+
|
|
128
206
|
<View style={{ flexDirection: 'row' }}>
|
|
129
207
|
<Switch value={shouldSetInitialFocus} onValueChange={onInitialFocusChange} />
|
|
130
208
|
<Text>Set Initial Focus</Text>
|
|
@@ -189,7 +267,11 @@ const StandardCallout: React.FunctionComponent = () => {
|
|
|
189
267
|
<Separator vertical />
|
|
190
268
|
|
|
191
269
|
<View style={{ flexDirection: 'column', paddingHorizontal: 5 }}>
|
|
192
|
-
<Button
|
|
270
|
+
<Button
|
|
271
|
+
content={(openCalloutOnHoverAnchor ? 'Hover Color Anchor ' : 'Press Here ') + 'for Callout'}
|
|
272
|
+
onClick={toggleShowStandardCallout}
|
|
273
|
+
disabled={openCalloutOnHoverAnchor}
|
|
274
|
+
/>
|
|
193
275
|
<Text>
|
|
194
276
|
<Text>Visibility: </Text>
|
|
195
277
|
{isStandardCalloutVisible ? <Text style={{ color: 'green' }}>Visible</Text> : <Text style={{ color: 'red' }}>Not Visible</Text>}
|
|
@@ -199,9 +281,30 @@ const StandardCallout: React.FunctionComponent = () => {
|
|
|
199
281
|
<Separator vertical />
|
|
200
282
|
|
|
201
283
|
<View style={{ flexDirection: 'column', paddingHorizontal: 5 }}>
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
|
|
284
|
+
<Pressable
|
|
285
|
+
onHoverIn={() => updateCalloutTargetsHoverState(true, redTargetRef)}
|
|
286
|
+
onHoverOut={() => updateCalloutTargetsHoverState(false, redTargetRef)}
|
|
287
|
+
>
|
|
288
|
+
<View ref={redTargetRef} style={{ height: 40, width: 40, backgroundColor: 'red', padding: 5 }}>
|
|
289
|
+
{anchorRefsInfo.isCurrentAnchor[0] && <Text>{anchorRefsInfo.hoverCount}</Text>}
|
|
290
|
+
</View>
|
|
291
|
+
</Pressable>
|
|
292
|
+
<Pressable
|
|
293
|
+
onHoverIn={() => updateCalloutTargetsHoverState(true, greenTargetRef)}
|
|
294
|
+
onHoverOut={() => updateCalloutTargetsHoverState(false, greenTargetRef)}
|
|
295
|
+
>
|
|
296
|
+
<View ref={greenTargetRef} style={{ height: 40, width: 40, backgroundColor: 'green', padding: 5 }}>
|
|
297
|
+
{anchorRefsInfo.isCurrentAnchor[1] && <Text>{anchorRefsInfo.hoverCount}</Text>}
|
|
298
|
+
</View>
|
|
299
|
+
</Pressable>
|
|
300
|
+
<Pressable
|
|
301
|
+
onHoverIn={() => updateCalloutTargetsHoverState(true, blueTargetRef)}
|
|
302
|
+
onHoverOut={() => updateCalloutTargetsHoverState(false, blueTargetRef)}
|
|
303
|
+
>
|
|
304
|
+
<View ref={blueTargetRef} style={{ height: 40, width: 40, backgroundColor: 'blue', padding: 5 }}>
|
|
305
|
+
{anchorRefsInfo.isCurrentAnchor[2] && <Text style={{ color: 'white' }}>{anchorRefsInfo.hoverCount}</Text>}
|
|
306
|
+
</View>
|
|
307
|
+
</Pressable>
|
|
205
308
|
</View>
|
|
206
309
|
</View>
|
|
207
310
|
|
|
@@ -215,6 +318,7 @@ const StandardCallout: React.FunctionComponent = () => {
|
|
|
215
318
|
{showStandardCallout && (
|
|
216
319
|
<Callout
|
|
217
320
|
{...{
|
|
321
|
+
doNotTakePointerCapture: openCalloutOnHoverAnchor ?? undefined,
|
|
218
322
|
target: anchorRef,
|
|
219
323
|
onDismiss: onDismissStandardCallout,
|
|
220
324
|
onShow: onShowStandardCallout,
|
|
@@ -228,23 +332,25 @@ const StandardCallout: React.FunctionComponent = () => {
|
|
|
228
332
|
...(calloutDismissBehaviors && { dismissBehaviors: calloutDismissBehaviors }),
|
|
229
333
|
}}
|
|
230
334
|
>
|
|
231
|
-
{
|
|
232
|
-
|
|
233
|
-
<
|
|
234
|
-
<
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
<
|
|
246
|
-
|
|
247
|
-
|
|
335
|
+
<Pressable onHoverIn={() => calloutHoveredCallback(true)} onHoverOut={() => calloutHoveredCallback(false)}>
|
|
336
|
+
{showScrollViewCallout ? (
|
|
337
|
+
<View style={fluentTesterStyles.scrollViewContainer}>
|
|
338
|
+
<ScrollView contentContainerStyle={fluentTesterStyles.scrollViewStyle} showsVerticalScrollIndicator={true}>
|
|
339
|
+
<StealthButton content="click to change anchor" onClick={toggleCalloutRef} />
|
|
340
|
+
<StealthButton content="Click to add a button" style={fluentTesterStyles.testListItem} onClick={addButton} />
|
|
341
|
+
<StealthButton content="Click to remove a button" style={fluentTesterStyles.testListItem} onClick={removeButton} />
|
|
342
|
+
{scrollviewContents.map((value) => {
|
|
343
|
+
return <StealthButton key={value} content="Button" style={fluentTesterStyles.testListItem} />;
|
|
344
|
+
})}
|
|
345
|
+
</ScrollView>
|
|
346
|
+
</View>
|
|
347
|
+
) : (
|
|
348
|
+
//else
|
|
349
|
+
<View style={[{ padding: 20 }, { backgroundColor: calloutHovered ? 'lightgreen' : 'pink' }]}>
|
|
350
|
+
<Button content="click to change anchor" onClick={toggleCalloutRef} />
|
|
351
|
+
</View>
|
|
352
|
+
)}
|
|
353
|
+
</Pressable>
|
|
248
354
|
</Callout>
|
|
249
355
|
)}
|
|
250
356
|
</View>
|