fix (app): mobile sidebar web interactions (#900)
* fix mobile sidebar web interactions * fix(app): restore button role on sidebar project row --------- Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
co-authored by
Mohamed Boudra
parent
e309d82b41
commit
35c582913d
@@ -89,6 +89,12 @@ function SortableItem<T>({
|
||||
}),
|
||||
[combinedTransform, transition, isDragging],
|
||||
);
|
||||
const {
|
||||
role: _dragRole,
|
||||
tabIndex: _dragTabIndex,
|
||||
"aria-roledescription": _dragRoleDescription,
|
||||
...dragHandleAttributes
|
||||
} = attributes as unknown as Record<string, unknown>;
|
||||
|
||||
const info: DraggableRenderItemInfo<T> = {
|
||||
item,
|
||||
@@ -97,7 +103,7 @@ function SortableItem<T>({
|
||||
isActive: activeId === id,
|
||||
dragHandleProps: useDragHandle
|
||||
? {
|
||||
attributes: attributes as unknown as Record<string, unknown>,
|
||||
attributes: dragHandleAttributes,
|
||||
listeners: listeners as unknown as Record<string, unknown>,
|
||||
setActivatorNodeRef: setActivatorNodeRef as unknown as (node: unknown) => void,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { router, usePathname } from "expo-router";
|
||||
import { FolderPlus, MessagesSquare, Settings } from "lucide-react-native";
|
||||
import { FolderPlus, MessagesSquare, Settings, X } from "lucide-react-native";
|
||||
import {
|
||||
type Dispatch,
|
||||
memo,
|
||||
@@ -679,6 +679,25 @@ function MobileSidebar({
|
||||
isActive={isSessionsActive}
|
||||
testID="sidebar-sessions"
|
||||
/>
|
||||
<Pressable
|
||||
style={styles.mobileCloseButton}
|
||||
onPress={closeToAgent}
|
||||
testID="sidebar-close"
|
||||
nativeID="sidebar-close"
|
||||
accessible
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Close sidebar"
|
||||
hitSlop={8}
|
||||
>
|
||||
{({ hovered, pressed }) => (
|
||||
<X
|
||||
size={theme.iconSize.md}
|
||||
color={
|
||||
hovered || pressed ? theme.colors.foreground : theme.colors.foregroundMuted
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Pressable>
|
||||
|
||||
{isInitialLoad ? (
|
||||
<SidebarAgentListSkeleton />
|
||||
@@ -888,6 +907,18 @@ const styles = StyleSheet.create((theme) => ({
|
||||
flex: 1,
|
||||
minHeight: 0,
|
||||
},
|
||||
mobileCloseButton: {
|
||||
position: "absolute",
|
||||
top: theme.spacing[3],
|
||||
right: theme.spacing[4],
|
||||
zIndex: 2,
|
||||
width: 32,
|
||||
height: 32,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
borderRadius: theme.borderRadius.lg,
|
||||
backgroundColor: theme.colors.surfaceSidebar,
|
||||
},
|
||||
desktopSidebarBorder: {
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: theme.colors.border,
|
||||
|
||||
@@ -594,7 +594,7 @@ function ProjectKebabMenu({
|
||||
<DropdownMenuTrigger
|
||||
hitSlop={8}
|
||||
style={projectKebabStyle}
|
||||
accessibilityRole="button"
|
||||
accessibilityRole={platformIsWeb ? undefined : "button"}
|
||||
accessibilityLabel="Project actions"
|
||||
testID={`sidebar-project-kebab-${projectKey}`}
|
||||
>
|
||||
@@ -725,7 +725,7 @@ function WorkspaceKebabMenu({
|
||||
<DropdownMenuTrigger
|
||||
hitSlop={8}
|
||||
style={workspaceKebabStyle}
|
||||
accessibilityRole="button"
|
||||
accessibilityRole={platformIsWeb ? undefined : "button"}
|
||||
accessibilityLabel="Workspace actions"
|
||||
testID={`sidebar-workspace-kebab-${workspaceKey}`}
|
||||
>
|
||||
@@ -895,7 +895,7 @@ function NewWorktreeButton({
|
||||
style={pressableStyle}
|
||||
onPress={handlePress}
|
||||
disabled={loading}
|
||||
accessibilityRole="button"
|
||||
accessibilityRole={platformIsWeb ? undefined : "button"}
|
||||
accessibilityLabel={`Create a new workspace for ${displayName}`}
|
||||
testID={testID}
|
||||
>
|
||||
@@ -1187,6 +1187,12 @@ function ProjectHeaderRow({
|
||||
drag,
|
||||
menuController,
|
||||
});
|
||||
const {
|
||||
role: _dragRole,
|
||||
tabIndex: _dragTabIndex,
|
||||
"aria-roledescription": _dragRoleDescription,
|
||||
...dragAttributes
|
||||
} = dragHandleProps?.attributes ?? {};
|
||||
|
||||
const handlePress = useCallback(() => {
|
||||
if (interaction.didLongPressRef.current) {
|
||||
@@ -1250,7 +1256,7 @@ function ProjectHeaderRow({
|
||||
if (menuController) {
|
||||
return (
|
||||
<View
|
||||
{...dragHandleProps?.attributes}
|
||||
{...dragAttributes}
|
||||
{...dragHandleProps?.listeners}
|
||||
ref={dragHandleProps?.setActivatorNodeRef as unknown as Ref<View>}
|
||||
onPointerEnter={handlePointerEnter}
|
||||
@@ -1258,6 +1264,7 @@ function ProjectHeaderRow({
|
||||
>
|
||||
<ContextMenuTrigger
|
||||
enabledOnMobile={false}
|
||||
accessibilityRole="button"
|
||||
style={projectRowStyle}
|
||||
onPressIn={interaction.handlePressIn}
|
||||
onTouchMove={interaction.handleTouchMove}
|
||||
@@ -1273,13 +1280,14 @@ function ProjectHeaderRow({
|
||||
|
||||
return (
|
||||
<View
|
||||
{...dragHandleProps?.attributes}
|
||||
{...dragAttributes}
|
||||
{...dragHandleProps?.listeners}
|
||||
ref={dragHandleProps?.setActivatorNodeRef as unknown as Ref<View>}
|
||||
onPointerEnter={handlePointerEnter}
|
||||
onPointerLeave={handlePointerLeave}
|
||||
>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
style={projectRowStyle}
|
||||
onPressIn={interaction.handlePressIn}
|
||||
onTouchMove={interaction.handleTouchMove}
|
||||
@@ -1328,6 +1336,12 @@ function WorkspaceRowInner({
|
||||
drag,
|
||||
menuController,
|
||||
});
|
||||
const {
|
||||
role: _dragRole,
|
||||
tabIndex: _dragTabIndex,
|
||||
"aria-roledescription": _dragRoleDescription,
|
||||
...dragAttributes
|
||||
} = dragHandleProps?.attributes ?? {};
|
||||
|
||||
const handlePress = useCallback(() => {
|
||||
if (interaction.didLongPressRef.current) {
|
||||
@@ -1369,7 +1383,7 @@ function WorkspaceRowInner({
|
||||
return (
|
||||
<WorkspaceHoverCard workspace={workspace} prHint={prHint} isDragging={isDragging}>
|
||||
<View
|
||||
{...dragHandleProps?.attributes}
|
||||
{...dragAttributes}
|
||||
{...dragHandleProps?.listeners}
|
||||
ref={dragHandleProps?.setActivatorNodeRef as unknown as Ref<View>}
|
||||
style={styles.workspaceRowContainer}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
type ReactElement,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import { Dimensions, Platform, Text, View } from "react-native";
|
||||
import { Dimensions, Text, View } from "react-native";
|
||||
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
|
||||
import { StyleSheet, withUnistyles } from "react-native-unistyles";
|
||||
import { CircleCheck, CircleDot, CircleX, ExternalLink } from "lucide-react-native";
|
||||
@@ -23,6 +23,8 @@ import type { PrHint } from "@/git/use-pr-status-query";
|
||||
import { openExternalUrl } from "@/utils/open-external-url";
|
||||
import { PrBadge } from "@/components/sidebar-workspace-list";
|
||||
import { useHoverSafeZone } from "@/hooks/use-hover-safe-zone";
|
||||
import { useIsCompactFormFactor } from "@/constants/layout";
|
||||
import { isWeb } from "@/constants/platform";
|
||||
|
||||
interface Rect {
|
||||
x: number;
|
||||
@@ -84,8 +86,9 @@ export function WorkspaceHoverCard({
|
||||
isDragging,
|
||||
children,
|
||||
}: PropsWithChildren<WorkspaceHoverCardProps>): ReactNode {
|
||||
// Desktop-only: skip on non-web platforms
|
||||
if (Platform.OS !== "web") {
|
||||
const isCompact = useIsCompactFormFactor();
|
||||
|
||||
if (!isWeb || isCompact) {
|
||||
return children;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user