Q201: an input method's Enter never picks a mention, and suggestions are announced
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
11369f8fed
commit
ca7721358e
3 files changed
+50
-3
No files matched your search
@@ -698,6 +698,7 @@ export const zh: Record<string, string> = {
|
||||
"Working…": "处理中…",
|
||||
"Waiting for the {name} sign-in in your browser (check {check} of {checks}).": "正在等待你在浏览器中完成 {name} 登录(第 {check}/{checks} 次检查)。",
|
||||
"Stop waiting": "停止等待",
|
||||
"People to mention": "可提及的人",
|
||||
"Layout": "布局",
|
||||
"View": "视图",
|
||||
"Run status": "运行状态",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useRef, useState, type MutableRefObject } from "react";
|
||||
import { t } from "../../i18n/i18n";
|
||||
import { useId, useRef, useState, type MutableRefObject } from "react";
|
||||
import { Avatar } from "../../shared/ui";
|
||||
import type { AgentRecord, EmployeeRecord } from "../../../../shared/domain";
|
||||
import { canonicalMentionHandle } from "../../../../shared/mention-handles";
|
||||
@@ -40,6 +41,7 @@ export function MentionTextarea({
|
||||
}) {
|
||||
const [query, setQuery] = useState<string | null>(null);
|
||||
const [index, setIndex] = useState(0);
|
||||
const listId = useId();
|
||||
const anchor = useRef(0);
|
||||
const innerRef = useRef<HTMLTextAreaElement | null>(null);
|
||||
const ref = textareaRef ?? innerRef;
|
||||
@@ -52,6 +54,7 @@ export function MentionTextarea({
|
||||
: [];
|
||||
|
||||
const close = () => setQuery(null);
|
||||
const open = !disabled && query !== null && filtered.length > 0;
|
||||
|
||||
const insertMention = (handle: string) => {
|
||||
const node = ref.current;
|
||||
@@ -81,6 +84,8 @@ export function MentionTextarea({
|
||||
};
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
// While an input method is composing, Enter and Tab confirm its text; they never pick a person or send.
|
||||
if (event.nativeEvent.isComposing || event.keyCode === 229) return;
|
||||
if (query !== null && filtered.length > 0) {
|
||||
if (event.key === "ArrowDown") {
|
||||
event.preventDefault();
|
||||
@@ -111,8 +116,8 @@ export function MentionTextarea({
|
||||
|
||||
return (
|
||||
<div style={{ position: "relative" }}>
|
||||
{!disabled && query !== null && filtered.length > 0 && (
|
||||
<div style={{
|
||||
{open && (
|
||||
<div id={listId} role="listbox" aria-label={t("People to mention")} style={{
|
||||
position: "absolute",
|
||||
bottom: "100%",
|
||||
left: 0,
|
||||
@@ -129,7 +134,11 @@ export function MentionTextarea({
|
||||
{filtered.map((c, i) => (
|
||||
<button
|
||||
key={c.handle}
|
||||
id={`${listId}-${i}`}
|
||||
type="button"
|
||||
role="option"
|
||||
aria-selected={i === index}
|
||||
tabIndex={-1}
|
||||
onMouseDown={(e) => { e.preventDefault(); insertMention(c.handle); }}
|
||||
style={{
|
||||
display: "flex",
|
||||
@@ -158,6 +167,9 @@ export function MentionTextarea({
|
||||
rows={rows}
|
||||
disabled={disabled}
|
||||
aria-label={ariaLabel}
|
||||
aria-autocomplete="list"
|
||||
aria-controls={open ? listId : undefined}
|
||||
aria-activedescendant={open ? `${listId}-${index}` : undefined}
|
||||
style={{
|
||||
width: "100%",
|
||||
border: 0,
|
||||
|
||||
Reference in new issue
Block a user