feat(web): give block editor an accessible dialog label
Expose role=dialog and a stable aria-label so save can be scoped without changing the modal's visuals or save behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import katex from 'katex';
|
||||
import { renderInlineMarkdown } from '../../engine/renderMarkdown';
|
||||
import { BLOCK_EDITOR_DIALOG_LABEL, BLOCK_EDITOR_SAVE_NAME } from '../../lib/blockEditorDialog';
|
||||
|
||||
interface BlockEditorModalProps {
|
||||
block: DocumentBlock;
|
||||
@@ -216,6 +217,9 @@ export const BlockEditorModal: React.FC<BlockEditorModalProps> = ({ block, onSav
|
||||
|
||||
return (
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label={BLOCK_EDITOR_DIALOG_LABEL}
|
||||
style={{
|
||||
position: 'fixed',
|
||||
inset: 0,
|
||||
@@ -973,7 +977,7 @@ export const BlockEditorModal: React.FC<BlockEditorModalProps> = ({ block, onSav
|
||||
}}
|
||||
>
|
||||
<Check size={14} />
|
||||
<span>保存修改</span>
|
||||
<span>{BLOCK_EDITOR_SAVE_NAME}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { describe, it } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {
|
||||
BLOCK_EDITOR_DIALOG_LABEL,
|
||||
BLOCK_EDITOR_SAVE_NAME,
|
||||
blockEditorDialogPolicy,
|
||||
} from './blockEditorDialog';
|
||||
|
||||
describe('blockEditorDialogPolicy', () => {
|
||||
it('pins an accessible dialog label and exact save name', () => {
|
||||
const policy = blockEditorDialogPolicy();
|
||||
assert.equal(policy.role, 'dialog');
|
||||
assert.equal(policy.name, '编辑受控块');
|
||||
assert.equal(policy.name, BLOCK_EDITOR_DIALOG_LABEL);
|
||||
assert.equal(policy.saveButton.name, '保存修改');
|
||||
assert.equal(policy.saveButton.name, BLOCK_EDITOR_SAVE_NAME);
|
||||
assert.equal(policy.saveButton.exact, true);
|
||||
});
|
||||
|
||||
it('rejects page-wide fuzzy /保存/ that would hit private-library buttons', () => {
|
||||
const policy = blockEditorDialogPolicy();
|
||||
const privateLibrary = '一键保存到我的私密文档库';
|
||||
assert.match(privateLibrary, policy.forbidPageWideSaveRegex);
|
||||
assert.equal(policy.saveButton.name === '保存修改', true);
|
||||
assert.doesNotMatch(policy.saveButton.name, /^一键保存/);
|
||||
assert.equal(policy.forbidPageWideSaveRegex.source, '保存修改|保存');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/** 块编辑弹窗的稳定可访问名称与保存按钮文案(禁止全页模糊 /保存/)。 */
|
||||
export const BLOCK_EDITOR_DIALOG_LABEL = '编辑受控块';
|
||||
export const BLOCK_EDITOR_SAVE_NAME = '保存修改';
|
||||
|
||||
export function blockEditorDialogPolicy(): {
|
||||
role: 'dialog';
|
||||
name: typeof BLOCK_EDITOR_DIALOG_LABEL;
|
||||
saveButton: { name: typeof BLOCK_EDITOR_SAVE_NAME; exact: true };
|
||||
forbidPageWideSaveRegex: RegExp;
|
||||
} {
|
||||
return {
|
||||
role: 'dialog',
|
||||
name: BLOCK_EDITOR_DIALOG_LABEL,
|
||||
saveButton: { name: BLOCK_EDITOR_SAVE_NAME, exact: true },
|
||||
forbidPageWideSaveRegex: /保存修改|保存/,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user