You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-simple-keyboard无法切换为阿拉伯语布局求助(React 18.2.0)

解决react-simple-keyboard切换阿拉伯语布局失败的问题

要实现阿拉伯语键盘布局,需要自定义阿拉伯语键盘布局配置,同时开启RTL(从右到左)渲染支持,以下是具体修改步骤:

1. 定义阿拉伯语布局

在组件中添加阿拉伯语的default和shift布局配置,对应阿拉伯语标准按键排列:

const arabicLayout = {
  default: [
    "ض ص ث ق ف غ ع ه خ ح ج د",
    "ش س ي ب ل ا ت ن م ك ط",
    "ئ ء ؤ ر ى ة ؤ ز و . ,",
    "{shift} {backspace}",
    "{space} {enter}"
  ],
  shift: [
    "ظ ض ص ث ق ف غ ع ه خ ح ج",
    "خ ح ج د ش س ي ب ل ا ت ن",
    "م ك ط ئ ء ؤ ر ى ة ؤ ز",
    "{shift} {backspace}",
    "{space} {enter}"
  ]
};

2. 新增语言布局控制状态

添加状态变量管理当前使用的语言布局,支持阿拉伯语与默认英文布局切换:

const [currentLanguage, setCurrentLanguage] = useState("arabic");

3. 配置Keyboard组件的RTL与布局

修改Keyboard组件的props,传入自定义布局并开启RTL适配:

<Keyboard
  keyboardRef={r => (keyboard.current = r)}
  layoutName={layout}
  layout={currentLanguage === "arabic" ? arabicLayout : undefined}
  onChange={onChange}
  onKeyPress={onKeyPress}
  rtl={currentLanguage === "arabic"}
/>

4. 调整输入与切换逻辑

  • 同步输入框与键盘的状态值,避免数据不一致
  • 添加语言切换按钮,动态调整输入框文本对齐方式
  • 修正原代码中错误的按键标识({<enter}改为标准{enter})

修改后的完整组件代码

import IconButton from "@mui/material/IconButton";
import SearchIcon from "@mui/icons-material/Search";
import TextField from "@mui/material/TextField";
import React, { useState, useRef, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import Tooltip from "@mui/material/Tooltip";
import FormControl from '@mui/material/FormControl';
import Keyboard from "react-simple-keyboard";
import "react-simple-keyboard/build/css/index.css";
import Button from '@mui/material/Button';

const SearchBar = () => {
  const [inputValue, setInputValue] = useState("");
  let navigate = useNavigate();
  const [input, setInput] = useState("");
  const [layout, setLayout] = useState("default");
  const [currentLanguage, setCurrentLanguage] = useState("arabic");
  const keyboard = useRef();
  const [keyboardVisibility, setKeyboardVisibility] = useState(false);

  // 阿拉伯语键盘布局
  const arabicLayout = {
    default: [
      "ض ص ث ق ف غ ع ه خ ح ج د",
      "ش س ي ب ل ا ت ن م ك ط",
      "ئ ء ؤ ر ى ة ؤ ز و . ,",
      "{shift} {backspace}",
      "{space} {enter}"
    ],
    shift: [
      "ظ ض ص ث ق ف غ ع ه خ ح ج",
      "خ ح ج د ش س ي ب ل ا ت ن",
      "م ك ط ئ ء ؤ ر ى ة ؤ ز",
      "{shift} {backspace}",
      "{space} {enter}"
    ]
  };

  useEffect(() => {
    function clickHandler(e) {
      if (
        !(e.target.nodeName === "INPUT") &&
        !e.target.classList.contains("hg-button") &&
        !e.target.classList.contains("hg-row")
      ) {
        setKeyboardVisibility(false);
      }
    }

    window.addEventListener("click", clickHandler);
    return () => window.removeEventListener("click", clickHandler, true);
  }, []);

  const onChange = (input) => {
    setInput(input);
    setInputValue(input);
    console.log("Input changed", input);
  };

  const handleShift = () => {
    const newLayoutName = layout === "default" ? "shift" : "default";
    setLayout(newLayoutName);
  };

  const onKeyPress = (button) => {
    console.log("Button pressed", button);
    if (button === "{shift}" || button === "{lock}") {
      handleShift();
    } else if (button === "{enter}") {
      onSearch(new Event("submit"));
    }
  };

  const handleChange = (e) => {
    const inputVal = e.target.value;
    setInput(inputVal);
    setInputValue(inputVal);
    keyboard.current?.setInput(inputVal);
  };

  const onSearch = (event) => {
    event.preventDefault();
    if (inputValue.length >= 1) {
      navigate("/SearchResult");
    }
  };

  return (
    <form>
      {/* 语言切换按钮 */}
      <Button 
        variant="outlined" 
        size="small"
        onClick={() => setCurrentLanguage(prev => prev === "arabic" ? "english" : "arabic")}
        sx={{ mb: 2 }}
      >
        切换{currentLanguage === "arabic" ? "英文" : "阿拉伯语"}键盘
      </Button>

      <TextField
        InputProps={{
          startAdornment: (
            <FormControl sx={{ mr: 35 }}>
              <Tooltip title="Search" placement="bottom">
                <IconButton type="submit" aria-label="search" onClick={onSearch}>
                  <SearchIcon sx={{ p: '10px' }}/>
                </IconButton>
              </Tooltip>
            </FormControl>
          ),
        }}
        id="search-bar"
        className="text"
        onChange={handleChange}
        value={input}
        variant="outlined"
        placeholder=""
        size="small"
        inputProps={{ style: { textAlign: currentLanguage === "arabic" ? 'right' : 'left' } }}
        onFocus={() => setKeyboardVisibility(true)}
      />

      {keyboardVisibility && (
        <Keyboard
          keyboardRef={r => (keyboard.current = r)}
          layoutName={layout}
          layout={currentLanguage === "arabic" ? arabicLayout : undefined}
          onChange={onChange}
          onKeyPress={onKeyPress}
          rtl={currentLanguage === "arabic"}
        />
      )}
    </form>
  );
};

export default SearchBar;

关键修改说明

  • 布局自定义:按照阿拉伯语键盘标准排列定义按键布局,覆盖默认英文配置
  • RTL适配:开启rtl属性,让键盘和输入框适配阿拉伯语从右到左的书写习惯
  • 状态同步:统一管理输入框和键盘的输入值,避免数据不一致问题
  • 错误修复:修正原代码中错误的{<enter}按键标识,改为标准的{enter}

内容的提问来源于stack exchange,提问作者SimoDevStuff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:03:32