@eddydesk/react-native

中文文档
0.14.9发布于 2026/09/27MITTypeScriptESM + CJS零依赖近 30 天下载 4516

EddyDesk React Native components for mobile apps

原始使用文档
文档目录19 节
  1. Installation
  2. Optional: Image attachments
  3. Quick Start
  4. Configuration Options
  5. Why use getAppContext ?
  6. Automatic Context Capture
  7. Navigation Tracking
  8. React Navigation integration
  9. Widget Architecture
  10. Button Configuration
  11. Monorepo Setup
  12. Fix: Configure Metro to use a single React instance
  13. Alternative: Yarn/npm Workspaces hoisting
  14. Troubleshooting
  15. Widget not showing
  16. Supabase connection issues
  17. Known Limitations
  18. Button hidden behind modals
  19. License

@eddydesk/react-native

EddyDesk QA widget for React Native mobile apps. Features a navigation-stack-based UI with 10 dedicated screens for testing, bug reporting, messaging, and profile management.

Installation

npm install @eddydesk/react-native @eddydesk/core
# or
yarn add @eddydesk/react-native @eddydesk/core

Optional: Image attachments

For image attachments in bug reports and messages:

npm install react-native-image-picker

This is an optional peer dependency — the widget works without it but won't show image picker buttons.

Quick Start

import { EddyDeskProvider, EddyDeskButton } from '@eddydesk/react-native';

function App() {
  return (
    <EddyDeskProvider
      config={{
        projectId: 'your-project-id',
        dashboardUrl: 'https://app.eddydesk.ai',
        getCurrentUser: async () => ({
          id: user.id,
          email: user.email,
          name: user.name, // Optional, shown on reports
        }),
      }}
    >
      <YourApp />
      <EddyDeskButton position="bottom-right" />
    </EddyDeskProvider>
  );
}

Configuration Options

<EddyDeskProvider
  config={{
    // Required
    projectId: 'your-project-id',
    getCurrentUser: async () => ({ id: user.id, email: user.email }),

    // Optional — rich context for bug reports
    getAppContext: () => ({
      currentRoute: currentScreenName,           // Current screen name
      userRole: currentUser?.role,                // 'owner', 'manager', 'guest', etc.
      propertyId: selectedProperty?.id,           // App-specific context
      custom: { theme: 'dark' },                 // Any additional data
    }),

    // Optional — callbacks
    dashboardUrl: 'https://app.eddydesk.ai',              // Web dashboard link in widget
    onNavigate: (route) => navigation.navigate(route),   // Deep link handler for test cases
    onReportSubmitted: (report) => { ... },               // After report submission
    getNavigationHistory: () => [...recentScreens],       // Custom nav tracking

    // Optional — self-hosted
    supabaseUrl: '...',
    supabaseAnonKey: '...',
  }}
  enabled={isAuthReady} // Delay init until auth is ready (default: true)
>

Why use getAppContext?

When a tester reports a bug, EddyDesk attaches the app context to the report. This tells the developer fixing the bug:

  • Which screen the bug is on
  • What role the user has (critical for role-dependent bugs)
  • App-specific state like selected property, active filters, etc.

The bug report form also includes a "Which screen?" field so testers can specify the affected screen manually.

Automatic Context Capture

EddyDeskProvider automatically captures debugging context with zero configuration:

DataDetails
Console logsLast 50 console.log/warn/error/info calls
Network requestsLast 20 fetch() calls with method, URL, status, duration
Failed response bodiesFirst 500 chars of 4xx/5xx response bodies
PerformancePage load time, memory usage
EnvironmentLanguage, timezone, online status

This data is attached to every bug report and available to the MCP server's get_report_context tool for AI-assisted debugging.

Note: For React Native, navigation history is not auto-captured (no pushState). Use getNavigationHistory or React Navigation integration below for screen tracking.

Navigation Tracking

React Navigation integration

import { useNavigationContainerRef } from '@react-navigation/native';

function App() {
  const navigationRef = useNavigationContainerRef();
  const routeHistory = useRef<string[]>([]);

  return (
    <EddyDeskProvider
      config={{
        projectId: 'your-project-id',
        getCurrentUser: async () => ({ id: user.id, email: user.email }),
        getNavigationHistory: () => routeHistory.current,
        getAppContext: () => ({
          currentRoute: navigationRef.getCurrentRoute()?.name || 'unknown',
          userRole: currentUser?.role,
        }),
      }}
    >
      <NavigationContainer
        ref={navigationRef}
        onStateChange={() => {
          const name = navigationRef.getCurrentRoute()?.name;
          if (name) {
            routeHistory.current.push(name);
            // Keep last 20
            if (routeHistory.current.length > 20) routeHistory.current.shift();
          }
        }}
      >
        {/* Your navigation */}
      </NavigationContainer>
      <EddyDeskButton />
    </EddyDeskProvider>
  );
}

Widget Architecture

The widget uses a navigation stack pattern with 12 screens:

ScreenPurpose
HomeSmart hero banner + 2x2 action grid + issue tracking cards (Open, Done, Reopened) + progress bar
Test ListAll assignments with filter tabs (All, To Do, Done, Re Opened) and colored status badges
Test DetailOne-test-at-a-time execution with pass/fail/skip actions
Test FeedbackStar rating + quality flags after pass/fail
ReportBug/feedback submission with type, severity, description, affected screen
Report SuccessConfirmation with auto-return to home
Issue ListIssues filtered by category (open/done/reopened) with severity indicators
Issue DetailFull issue details with verification proof and original bug context
Message ListThread list with unread badges + compose button
Thread DetailChat bubbles + reply composer
Compose MessageNew thread form with subject + message
ProfileTester info, stats, and editable fields

Button Configuration

The EddyDesk button is draggable by default with edge-snapping behavior:

<EddyDeskButton
  draggable={true}           // Enable/disable dragging (default: true)
  position="bottom-right"    // Initial position: 'bottom-right' | 'bottom-left'
  initialX={100}             // Custom initial X position (optional)
  initialY={500}             // Custom initial Y position (optional)
  minY={100}                 // Minimum Y from top (default: 100)
  maxYOffset={160}           // Max Y offset from bottom (default: 160)
/>

The button automatically snaps to the nearest screen edge when released.

Monorepo Setup

When using EddyDesk in a monorepo (e.g., with Turborepo, Nx, or Yarn Workspaces), you may encounter React duplicate instance errors like:

  • "Invalid hook call"
  • "Cannot read property 'useState' of null"
  • "Hooks can only be called inside the body of a function component"

This happens when Metro (React Native's bundler) picks up different React instances from different node_modules folders.

Fix: Configure Metro to use a single React instance

Update your metro.config.js in the React Native app:

const path = require('path');
const { getDefaultConfig } = require('@react-native/metro-config');

// Get the monorepo root (adjust path as needed)
const monorepoRoot = path.resolve(__dirname, '../..');

const config = getDefaultConfig(__dirname);

// Block React from monorepo root to prevent duplicates
config.resolver.blockList = [
  ...(config.resolver.blockList || []),
  new RegExp(`${monorepoRoot}/node_modules/react/.*`),
  new RegExp(`${monorepoRoot}/node_modules/react-native/.*`),
];

// Ensure Metro uses the app's React instance
config.resolver.extraNodeModules = {
  react: path.resolve(__dirname, 'node_modules/react'),
  'react-native': path.resolve(__dirname, 'node_modules/react-native'),
};

// Watch the monorepo packages
config.watchFolders = [
  monorepoRoot,
];

module.exports = config;

Alternative: Yarn/npm Workspaces hoisting

If you're using Yarn workspaces, you can also configure hoisting to ensure a single React version:

// package.json (workspace root)
{
  "workspaces": {
    "packages": ["apps/*", "packages/*"],
    "nohoist": [
      "**/react-native",
      "**/react-native/**"
    ]
  }
}

Troubleshooting

Widget not showing

  1. Make sure the current user's email is registered as a tester in the EddyDesk dashboard
  2. Verify QA mode is enabled for your project
  3. Check that getCurrentUser returns a valid email

Supabase connection issues

If you're using your own Supabase instance, provide the credentials:

<EddyDeskProvider
  config={{
    projectId: 'your-project-id',
    supabaseUrl: 'https://your-instance.supabase.co',
    supabaseAnonKey: 'your-anon-key',
    getCurrentUser: async () => ({ id: user.id, email: user.email }),
  }}
>

Known Limitations

Button hidden behind modals

The EddyDesk button renders within the normal React Native view hierarchy using absolute positioning. When your app displays modals, bottom sheets, or the keyboard, the button may be hidden behind them.

Workarounds:

  • Accept that the button won't be accessible when modals are open
  • Consider dismissing the modal to access EddyDesk
  • For testing flows that involve modals, provide an alternative way to trigger the EddyDesk widget

License

MIT

版本与发布记录

@eddydesk/react-native 共发布 14 个版本,首次发布于 2026/05/01;过去 12 个月发布了 14 个版本。

版本发布日期距今
0.14.9latest2026/09/271 个月前
0.14.82026/09/261 个月前
0.14.72026/09/171 个月前
0.14.62026/09/161 个月前
0.14.52026/09/161 个月前
0.14.42026/09/141 个月前

关于 @eddydesk/react-native 的常见问题

@eddydesk/react-native 是什么?

EddyDesk React Native components for mobile apps

如何安装 @eddydesk/react-native?

在项目目录运行 npm install @eddydesk/react-native,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^18.0.0 || ^19.0.0)、react-native(>=0.70.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@eddydesk/react-native 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@eddydesk/react-native 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@eddydesk/react-native 可以商用吗?

@eddydesk/react-native 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@eddydesk/react-native 的下载量有多少?

根据 npm 官方下载统计,@eddydesk/react-native 在 2026/10/13 – 2026/11/11 这 30 天内被下载 4,516 次,日均约 151 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@eddydesk/react-native 还在维护吗?

最新版本 0.14.9 发布于 2026/09/27(1 个月前);至今共发布 14 个版本,其中过去 12 个月发布了 14 个;首次发布于 2026/05/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。