fix: surface Magic Notes list shortcuts
Magic Notes already accepted Quill's native bullet, numbered, and checklist autofill, but the editor did not make those shortcuts discoverable or protect them with behavior coverage. The composer now explains the supported markers in both languages, and tests verify they continue producing Delta list formats. Release note: 魔法笔记编辑区现在提示项目符号、编号和待办清单快捷输入;输入标记后按空格即可创建对应列表。
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import Quill from 'quill'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type { MagicNoteRichContent } from '../../shared/magic-notes-contracts'
|
||||
import { MagicNoteEditor } from './MagicNoteEditor'
|
||||
@@ -45,6 +46,46 @@ describe('MagicNoteEditor', () => {
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it.each([
|
||||
['-', 'bullet'],
|
||||
['*', 'bullet'],
|
||||
['1.', 'ordered'],
|
||||
['[ ]', 'unchecked'],
|
||||
['[x]', 'checked']
|
||||
])(
|
||||
'keeps the native Quill %s list shortcut enabled',
|
||||
async (marker, expectedList) => {
|
||||
const onChange = vi.fn<(content: MagicNoteRichContent) => void>()
|
||||
const { container } = render(
|
||||
<MagicNoteEditor
|
||||
ariaLabel="笔记正文"
|
||||
onChange={onChange}
|
||||
onError={vi.fn()}
|
||||
/>
|
||||
)
|
||||
const editor = container.querySelector<HTMLElement>('.ql-editor')
|
||||
const quillContainer = container.querySelector<HTMLElement>(
|
||||
'.magic-note-editor__content'
|
||||
)
|
||||
expect(editor).not.toBeNull()
|
||||
expect(quillContainer).not.toBeNull()
|
||||
|
||||
const quill = Quill.find(quillContainer!) as Quill
|
||||
quill.setText(marker, 'user')
|
||||
quill.setSelection(marker.length, 0, 'silent')
|
||||
fireEvent.keyDown(editor!, { key: ' ' })
|
||||
|
||||
await waitFor(() => {
|
||||
const content = onChange.mock.calls.at(-1)?.[0]
|
||||
expect(
|
||||
content?.ops.some(
|
||||
(operation) => operation.attributes?.list === expectedList
|
||||
)
|
||||
).toBe(true)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
it('intercepts a pasted image before Quill and inserts it once', async () => {
|
||||
const onChange = vi.fn<(content: MagicNoteRichContent) => void>()
|
||||
const { container } = render(
|
||||
|
||||
@@ -86,9 +86,10 @@ export const magicNotes = {
|
||||
emptySelectionDescription:
|
||||
'Select a note on the left, or create a note to start writing.',
|
||||
newEntryLabel: 'New entry content',
|
||||
composerImmediateHint: 'AI comments after you stop typing for 5 seconds',
|
||||
composerImmediateHint:
|
||||
'Type -, 1., [ ], or [x] then Space to start a list; AI comments after 5 seconds of inactivity',
|
||||
composerRichTextHint:
|
||||
'Supports rich text and pasting or dropping local images, videos, and attachments',
|
||||
'Type -, 1., [ ], or [x] then Space to start a list; you can also paste or drop local files',
|
||||
emptyEntries: 'No entries yet. Write the first entry above.',
|
||||
editEntryLabel: 'Edit entry content',
|
||||
entryAt: '{{date}} entry'
|
||||
|
||||
@@ -80,8 +80,10 @@ export const magicNotes = {
|
||||
emptySelectionTitle: '还没有选择笔记',
|
||||
emptySelectionDescription: '从左侧选择笔记,或新建一篇笔记开始记录。',
|
||||
newEntryLabel: '新记录内容',
|
||||
composerImmediateHint: '停止输入 5 秒后自动评论',
|
||||
composerRichTextHint: '支持富文本,可粘贴或拖入本地图片、视频和附件',
|
||||
composerImmediateHint:
|
||||
'输入 -、1.、[ ] 或 [x] 后按空格可创建列表;停止输入 5 秒后自动评论',
|
||||
composerRichTextHint:
|
||||
'输入 -、1.、[ ] 或 [x] 后按空格可创建列表;也可粘贴或拖入本地文件',
|
||||
emptyEntries: '还没有记录,在上方写下第一条内容。',
|
||||
editEntryLabel: '编辑记录内容',
|
||||
entryAt: '{{date}} 的记录'
|
||||
|
||||
Reference in New Issue
Block a user