React Beautiful DND 多语言拖拽提示:i18next 集成与翻译文本管理

【免费下载链接】react-beautiful-dnd atlassian/react-beautiful-dnd: React Beautiful DND 是一个由Atlassian团队开发的高质量React拖放库,提供流畅的交互体验和丰富的自定义选项,广泛应用于创建可拖拽排序的列表和其他拖放功能。 【免费下载链接】react-beautiful-dnd 项目地址: https://gitcode.com/gh_mirrors/re/react-beautiful-dnd

React Beautiful DND 作为高质量的拖放库,其默认英文提示可能无法满足国际化应用需求。本文将详细介绍如何通过 i18next 实现拖拽提示的多语言支持,让你的应用轻松应对全球用户场景。

核心提示系统分析

React Beautiful DND 通过屏幕阅读器公告系统(Announcer)提供无障碍支持,所有交互提示均集中在以下两个核心文件中:

  • 公告器实现src/view/use-announcer/use-announcer.js
    该模块通过 aria-live 区域动态更新提示文本,第 60-77 行的 announce 函数负责将消息传递给屏幕阅读器。

  • 默认提示文本src/screen-reader-message-preset.js
    定义了拖拽全生命周期的提示模板,包括:

    • 拖拽启动:onDragStart 函数(第 28-30 行)
    • 拖拽更新:onDragUpdate 函数(第 77-89 行)
    • 拖拽结束:onDragEnd 函数(第 96-125 行)
    • 操作说明:dragHandleUsageInstructions 常量(第 18-22 行)

翻译方案设计

1. 项目结构调整

在现有项目中添加国际化相关目录:

src/
├── i18n/
│   ├── translations/
│   │   ├── en/
│   │   │   └── dragMessages.json
│   │   ├── zh-CN/
│   │   │   └── dragMessages.json
│   │   └── fr/
│   │       └── dragMessages.json
│   └── index.js          // i18next 配置
└── view/
    └── use-announcer/
        └── use-announcer.js  // 修改公告器使用翻译文本

2. i18next 配置实现

创建 src/i18n/index.js 配置 i18next:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import enDrag from './translations/en/dragMessages.json';
import zhCNDrag from './translations/zh-CN/dragMessages.json';
import frDrag from './translations/fr/dragMessages.json';

i18n
  .use(initReactI18next)
  .init({
    resources: {
      en: { drag: enDrag },
      'zh-CN': { drag: zhCNDrag },
      fr: { drag: frDrag }
    },
    lng: 'en', // 默认语言
    fallbackLng: 'en',
    ns: ['drag'], // 命名空间
    defaultNS: 'drag',
    interpolation: {
      escapeValue: false // React 已处理 XSS
    }
  });

export default i18n;

3. 翻译文件示例

创建中文翻译文件 src/i18n/translations/zh-CN/dragMessages.json:

{
  "dragHandleUsageInstructions": "按空格键开始拖拽。拖拽时可使用方向键移动项目,按ESC键取消。部分屏幕阅读器可能需要切换到焦点模式或使用穿透键。",
  "onDragStart": "您已选中位置 {{position}} 的项目",
  "onDragUpdateSameList": "您已将项目从位置 {{start}} 移动到位置 {{end}}",
  "onDragUpdateDifferentList": "您已将项目从 {{sourceList}} 的位置 {{start}} 移动到 {{destList}} 的位置 {{end}}",
  "onDragEndCancel": "操作已取消。项目已返回原位置 {{position}}",
  "onDragEndDropped": "项目已放置。{{locationText}}"
}

核心代码改造

1. 创建多语言提示预设

新建 src/screen-reader-message-i18n.js 替换默认提示:

import { useTranslation } from 'react-i18next';
import type { MessagePreset } from './types';

export default function useDragMessages(): MessagePreset {
  const { t } = useTranslation('drag');
  const position = (index: number) => index + 1;

  return {
    dragHandleUsageInstructions: t('dragHandleUsageInstructions'),
    
    onDragStart: (start) => t('onDragStart', { 
      position: position(start.source.index) 
    }),
    
    onDragUpdate: (update) => {
      if (!update.destination) return t('onDragUpdateInvalid');
      
      const isSameList = update.source.droppableId === update.destination.droppableId;
      return isSameList 
        ? t('onDragUpdateSameList', { 
            start: position(update.source.index),
            end: position(update.destination.index)
          })
        : t('onDragUpdateDifferentList', {
            sourceList: update.source.droppableId,
            destList: update.destination.droppableId,
            start: position(update.source.index),
            end: position(update.destination.index)
          });
    },
    
    onDragEnd: (result) => {
      if (result.reason === 'CANCEL') {
        return t('onDragEndCancel', { 
          position: position(result.source.index) 
        });
      }
      
      // 处理其他情况...
    }
  };
}

2. 修改公告器使用翻译文本

更新 src/view/use-announcer/use-announcer.js,在第 12 行导入多语言预设:

import useDragMessages from '../../screen-reader-message-i18n';

// 修改第 12 行
export default function useAnnouncer(contextId: ContextId): Announce {
  const messages = useDragMessages(); // 获取翻译后的消息
  // ... 保留原实现 ...
}

3. 集成到拖拽上下文

在应用入口处初始化 i18n 并提供翻译后的消息预设:

import { DragDropContext } from 'react-beautiful-dnd';
import { I18nextProvider } from 'react-i18next';
import i18n from './i18n';
import useDragMessages from './screen-reader-message-i18n';

function App() {
  const messages = useDragMessages();
  
  return (
    <I18nextProvider i18n={i18n}>
      <DragDropContext
        screenReaderMessageBuilder={messages}
        onDragEnd={handleDragEnd}
      >
        {/* 拖拽列表组件 */}
      </DragDropContext>
    </I18nextProvider>
  );
}

测试与验证

语言切换组件

创建语言切换器 src/components/LanguageSwitcher.jsx:

import { useTranslation } from 'react-i18next';

export default function LanguageSwitcher() {
  const { i18n } = useTranslation();
  
  return (
    <div>
      <button onClick={() => i18n.changeLanguage('en')}>English</button>
      <button onClick={() => i18n.changeLanguage('zh-CN')}>中文</button>
      <button onClick={() => i18n.changeLanguage('fr')}>Français</button>
    </div>
  );
}

验证场景

  1. 基础功能测试

    • 切换语言后检查所有拖拽状态的提示文本
    • 验证数字插值(如位置编号)是否正确
    • 测试取消拖拽、跨列表拖拽等边缘情况
  2. 无障碍测试: 使用 NVDA、VoiceOver 等屏幕阅读器验证:

    • 提示文本是否正确朗读
    • 语言切换是否实时生效
    • 操作流程是否符合无障碍规范

高级优化

1. 动态语言检测

根据浏览器设置自动选择语言:

// 在 src/i18n/index.js 中添加
const browserLang = navigator.language || navigator.userLanguage;
i18n.init({
  lng: browserLang.includes('zh') ? 'zh-CN' : browserLang.includes('fr') ? 'fr' : 'en',
  // ...其他配置
});

2. 翻译文本管理

对于大型项目,建议使用 i18next-http-backend 从服务器加载翻译文件,配合 i18next-browser-languagedetector 实现更复杂的语言检测逻辑。

总结

通过本文方案,你可以:

  1. 实现拖拽提示的完全国际化
  2. 支持动态语言切换
  3. 保持与原无障碍设计的兼容性
  4. 为未来新增语言提供可扩展框架

完整实现需配合官方文档中的 无障碍指南自定义提示 章节进行深入优化。

提示:所有翻译文件应定期更新,确保与 src/screen-reader-message-preset.js 中的最新提示模板保持同步。

【免费下载链接】react-beautiful-dnd atlassian/react-beautiful-dnd: React Beautiful DND 是一个由Atlassian团队开发的高质量React拖放库,提供流畅的交互体验和丰富的自定义选项,广泛应用于创建可拖拽排序的列表和其他拖放功能。 【免费下载链接】react-beautiful-dnd 项目地址: https://gitcode.com/gh_mirrors/re/react-beautiful-dnd

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐