diff --git a/resources/js/admin/mobile/components/__tests__/UserMenuSheet.test.tsx b/resources/js/admin/mobile/components/__tests__/UserMenuSheet.test.tsx
new file mode 100644
index 00000000..c1fa6114
--- /dev/null
+++ b/resources/js/admin/mobile/components/__tests__/UserMenuSheet.test.tsx
@@ -0,0 +1,92 @@
+import React from 'react';
+import { describe, expect, it, vi } from 'vitest';
+import { render } from '@testing-library/react';
+
+vi.mock('react-i18next', () => ({
+ useTranslation: () => ({ t: (key: string, fallback?: string) => fallback ?? key, i18n: { language: 'en-GB' } }),
+}));
+
+vi.mock('@tamagui/react-native-web-lite', () => ({
+ Pressable: ({ children, onPress, ...props }: { children: React.ReactNode; onPress?: () => void }) => (
+
+ ),
+}));
+
+vi.mock('tamagui', () => {
+ const Stack = ({ children, ...props }: { children: React.ReactNode }) => {children}
;
+ const Text = ({ children, ...props }: { children: React.ReactNode }) => {children};
+ const Switch = ({ children }: { children?: React.ReactNode }) => {children}
;
+ Switch.Thumb = () => ;
+
+ const ListItem = ({ title, iconAfter, ...props }: { title?: React.ReactNode; iconAfter?: React.ReactNode }) => (
+
+ {title}
+ {iconAfter}
+
+ );
+
+ const YGroup: any = ({ children }: { children: React.ReactNode }) => {children}
;
+ YGroup.Item = ({ children }: { children: React.ReactNode }) => {children}
;
+
+ return {
+ XStack: Stack,
+ YStack: Stack,
+ SizableText: Text,
+ ListItem,
+ YGroup,
+ Switch,
+ Separator: ({ children }: { children?: React.ReactNode }) => {children}
,
+ };
+});
+
+vi.mock('../FormControls', () => ({
+ MobileSelect: ({ children }: { children: React.ReactNode }) => ,
+}));
+
+vi.mock('@/hooks/use-appearance', () => ({
+ useAppearance: () => ({
+ appearance: 'system',
+ resolved: 'light',
+ updateAppearance: vi.fn(),
+ }),
+}));
+
+vi.mock('../../theme', () => ({
+ useAdminTheme: () => ({
+ overlay: 'rgba(0,0,0,0.3)',
+ surface: '#ffffff',
+ border: '#e5e7eb',
+ textStrong: '#111827',
+ muted: '#6b7280',
+ surfaceMuted: '#f3f4f6',
+ accentSoft: '#fef2f2',
+ primary: '#FF5A5F',
+ glassShadow: 'rgba(15,23,42,0.14)',
+ shadow: 'rgba(0,0,0,0.12)',
+ }),
+}));
+
+import { UserMenuSheet } from '../UserMenuSheet';
+
+const baseProps = {
+ onClose: vi.fn(),
+ user: { name: 'Ada Lovelace', email: 'ada@example.com' },
+ isMember: false,
+ navigate: vi.fn(),
+};
+
+describe('UserMenuSheet', () => {
+ it('slides in when open', () => {
+ const { getByTestId } = render();
+
+ expect(getByTestId('user-menu-sheet-panel').style.transform).toBe('translateX(0px)');
+ });
+
+ it('slides out when closed', () => {
+ const { getByTestId } = render();
+
+ expect(getByTestId('user-menu-sheet-panel').style.transform).toMatch(/translateX\(\d+px\)/);
+ });
+});