[Mac] [Focus Zone] Tweak tab\shift behavior (#3690)
This commit is contained in:
Родитель
b72ecbad0c
Коммит
434c367e8c
|
@ -181,6 +181,32 @@ const NestedFocusZone: React.FunctionComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const FocusZoneGrid: React.FunctionComponent = () => {
|
||||||
|
const [isCircularNavigation, setCircularNavigation] = React.useState(true);
|
||||||
|
const [tabNavigation, setTabNavigation] = React.useState<FocusZoneTabNavigation>('None');
|
||||||
|
const onCircularNavigationChange = React.useCallback((_, isChecked: boolean) => setCircularNavigation(isChecked), []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FocusZoneListWrapper>
|
||||||
|
<>
|
||||||
|
<Text>FocusZone Grid</Text>
|
||||||
|
<Checkbox label="Circular Navigation" checked={isCircularNavigation} onChange={onCircularNavigationChange} />
|
||||||
|
<MenuButton
|
||||||
|
content={`Tab key navigation: ${tabNavigation}`}
|
||||||
|
menuItems={FocusZoneTabNavigations.map((dir) => ({
|
||||||
|
itemKey: dir,
|
||||||
|
text: dir,
|
||||||
|
}))}
|
||||||
|
onItemClick={(dir) => setTabNavigation(dir as FocusZoneTabNavigation)}
|
||||||
|
/>
|
||||||
|
<FocusZone isCircularNavigation tabKeyNavigation={tabNavigation}>
|
||||||
|
<GridOfButtons gridWidth={3} gridHeight={3} />
|
||||||
|
</FocusZone>
|
||||||
|
</>
|
||||||
|
</FocusZoneListWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const focusZoneSections: TestSection[] = [
|
const focusZoneSections: TestSection[] = [
|
||||||
{
|
{
|
||||||
name: 'Common FocusZone Usage',
|
name: 'Common FocusZone Usage',
|
||||||
|
@ -215,6 +241,10 @@ const focusZoneSections: TestSection[] = [
|
||||||
name: 'Nested FocusZone',
|
name: 'Nested FocusZone',
|
||||||
component: NestedFocusZone,
|
component: NestedFocusZone,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'FocusZone Grid',
|
||||||
|
component: FocusZoneGrid,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const e2eSections: TestSection[] = [
|
const e2eSections: TestSection[] = [
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"type": "patch",
|
||||||
|
"comment": "[Mac] [Focus Zone] Tweak tab\\shift behavior",
|
||||||
|
"packageName": "@fluentui-react-native/focus-zone",
|
||||||
|
"email": "nakambo@microsoft.com",
|
||||||
|
"dependentChangeType": "patch"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"type": "patch",
|
||||||
|
"comment": "Add FocusZone Grid test case",
|
||||||
|
"packageName": "@fluentui-react-native/tester",
|
||||||
|
"email": "nakambo@microsoft.com",
|
||||||
|
"dependentChangeType": "patch"
|
||||||
|
}
|
|
@ -482,8 +482,6 @@ static BOOL ShouldSkipFocusZone(NSView *view)
|
||||||
{
|
{
|
||||||
NSView *nextViewToFocus;
|
NSView *nextViewToFocus;
|
||||||
|
|
||||||
[[self window] recalculateKeyViewLoop];
|
|
||||||
|
|
||||||
// Find the first view outside the FocusZone (or any parent FocusZones) to place focus
|
// Find the first view outside the FocusZone (or any parent FocusZones) to place focus
|
||||||
RCTFocusZone *focusZoneAncestor = GetFocusZoneAncestor(self);
|
RCTFocusZone *focusZoneAncestor = GetFocusZoneAncestor(self);
|
||||||
|
|
||||||
|
@ -527,6 +525,41 @@ static BOOL ShouldSkipFocusZone(NSView *view)
|
||||||
return nextViewToFocus;
|
return nextViewToFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSView *)nextViewToFocusForTab:(FocusZoneAction)action
|
||||||
|
{
|
||||||
|
[[self window] recalculateKeyViewLoop];
|
||||||
|
|
||||||
|
NSString *tabKeyNavigation = [self tabKeyNavigation];
|
||||||
|
if (![@"NavigateWrap" isEqual:tabKeyNavigation] && ![@"NavigateStopAtEnds" isEqual:tabKeyNavigation]
|
||||||
|
&& ![@"Normal" isEqual:tabKeyNavigation])
|
||||||
|
{
|
||||||
|
return [self nextViewToFocusOutsideZone:action];
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL forward = action != FocusZoneActionShiftTab;
|
||||||
|
NSView *firstResponder = GetFirstResponder([self window]);
|
||||||
|
NSView *nextViewToFocus = action == forward ? [firstResponder nextValidKeyView] : [firstResponder previousValidKeyView];
|
||||||
|
|
||||||
|
if (nextViewToFocus == self)
|
||||||
|
nextViewToFocus = action == forward ? [nextViewToFocus nextValidKeyView] : [nextViewToFocus previousValidKeyView];;
|
||||||
|
|
||||||
|
if ([@"Normal" isEqual:tabKeyNavigation] || [nextViewToFocus isDescendantOf:self])
|
||||||
|
return nextViewToFocus;
|
||||||
|
|
||||||
|
if ([@"NavigateStopAtEnds" isEqual:tabKeyNavigation])
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
// wrap around -- find first (tab) or last (shift+tab)
|
||||||
|
NSView *aView = firstResponder;
|
||||||
|
while (aView != self && [aView isDescendantOf:self])
|
||||||
|
{
|
||||||
|
nextViewToFocus = aView;
|
||||||
|
aView = forward ? [aView previousValidKeyView] : [aView nextValidKeyView];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextViewToFocus != firstResponder ? nextViewToFocus : nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)isFlipped
|
- (BOOL)isFlipped
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -537,11 +570,6 @@ static BOOL ShouldSkipFocusZone(NSView *view)
|
||||||
FocusZoneAction action = GetActionForEvent(event);
|
FocusZoneAction action = GetActionForEvent(event);
|
||||||
FocusZoneDirection focusZoneDirection = [self focusZoneDirection];
|
FocusZoneDirection focusZoneDirection = [self focusZoneDirection];
|
||||||
NSString *navigateAtEnd = [self navigateAtEnd];
|
NSString *navigateAtEnd = [self navigateAtEnd];
|
||||||
NSString *tabKeyNavigation = [self tabKeyNavigation];
|
|
||||||
|
|
||||||
BOOL tabAllowed = [@"NavigateWrap" isEqual:tabKeyNavigation]
|
|
||||||
|| [@"NavigateStopAtEnds" isEqual:tabKeyNavigation]
|
|
||||||
|| [@"Normal" isEqual:tabKeyNavigation];
|
|
||||||
|
|
||||||
BOOL passthrough = NO;
|
BOOL passthrough = NO;
|
||||||
NSView *viewToFocus = nil;
|
NSView *viewToFocus = nil;
|
||||||
|
@ -553,25 +581,13 @@ static BOOL ShouldSkipFocusZone(NSView *view)
|
||||||
{
|
{
|
||||||
passthrough = YES;
|
passthrough = YES;
|
||||||
}
|
}
|
||||||
else if (!tabAllowed && (action == FocusZoneActionTab || action == FocusZoneActionShiftTab))
|
else if (action == FocusZoneActionTab || action == FocusZoneActionShiftTab)
|
||||||
{
|
{
|
||||||
viewToFocus = [self nextViewToFocusOutsideZone:action];
|
viewToFocus = [self nextViewToFocusForTab:action];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FocusZoneAction directionalAction = action == FocusZoneActionTab ? FocusZoneActionDownArrow
|
viewToFocus = [self nextViewToFocusWithFallback:action considerCircular:[@"NavigateWrap" isEqual:navigateAtEnd]];
|
||||||
: (action == FocusZoneActionShiftTab ? FocusZoneActionUpArrow : action);
|
|
||||||
|
|
||||||
BOOL allowCircular = [@"NavigateWrap" isEqual:action == FocusZoneActionTab || action == FocusZoneActionShiftTab
|
|
||||||
? tabKeyNavigation : navigateAtEnd];
|
|
||||||
|
|
||||||
viewToFocus = [self nextViewToFocusWithFallback:directionalAction considerCircular:allowCircular];
|
|
||||||
|
|
||||||
if (viewToFocus == nil && action != directionalAction && [@"Normal" isEqual:tabKeyNavigation]) // tab, shift+tab
|
|
||||||
{
|
|
||||||
// didn't find a view IN the zone -- look outside
|
|
||||||
viewToFocus = [self nextViewToFocusOutsideZone:action];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewToFocus != nil)
|
if (viewToFocus != nil)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче