From 89ced5ec6b46c4e1b13495b2fdacdfd07c47b167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Jablo=C3=B1ski?= <43938777+GermanJablo@users.noreply.github.com> Date: Fri, 30 May 2025 18:28:51 -0300 Subject: [PATCH] fix(richtext-lexical): enable select inputs with ctrl+a or cmd+a (#12453) Fixes #6871 To review this PR, use `pnpm dev lexical` and the auto-created document in the `lexical fields` collection. Select any input within the blocks and press `cmd+a`. The selection should contain the entire input. I made sure that `cmd+a` still works fine inside the editor but outside of inputs. --- docs/authentication/overview.mdx | 4 +-- .../src/lexical/LexicalEditor.tsx | 2 ++ .../lexical/plugins/SelectAllPlugin/index.tsx | 32 +++++++++++++++++++ .../migrations/20250528_153134.ts | 2 +- .../_LexicalFullyFeatured/e2e.spec.ts | 18 +++++++++++ tsconfig.base.json | 2 +- 6 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 packages/richtext-lexical/src/lexical/plugins/SelectAllPlugin/index.tsx diff --git a/docs/authentication/overview.mdx b/docs/authentication/overview.mdx index 4a7009653..c32ea9074 100644 --- a/docs/authentication/overview.mdx +++ b/docs/authentication/overview.mdx @@ -151,8 +151,8 @@ export default buildConfig({ prefillOnly: true, } : false, - } - + }, + // highlight-end }) ``` diff --git a/packages/richtext-lexical/src/lexical/LexicalEditor.tsx b/packages/richtext-lexical/src/lexical/LexicalEditor.tsx index aa3a5f3d2..d7a2ddf18 100644 --- a/packages/richtext-lexical/src/lexical/LexicalEditor.tsx +++ b/packages/richtext-lexical/src/lexical/LexicalEditor.tsx @@ -19,6 +19,7 @@ import { DraggableBlockPlugin } from './plugins/handles/DraggableBlockPlugin/ind import { InsertParagraphAtEndPlugin } from './plugins/InsertParagraphAtEnd/index.js' import { MarkdownShortcutPlugin } from './plugins/MarkdownShortcut/index.js' import { NormalizeSelectionPlugin } from './plugins/NormalizeSelection/index.js' +import { SelectAllPlugin } from './plugins/SelectAllPlugin/index.js' import { SlashMenuPlugin } from './plugins/SlashMenu/index.js' import { TextPlugin } from './plugins/TextPlugin/index.js' import { LexicalContentEditable } from './ui/ContentEditable.js' @@ -111,6 +112,7 @@ export const LexicalEditor: React.FC< + { + return editor.registerCommand( + SELECT_ALL_COMMAND, + () => { + const selection = $getSelection() + if (selection) { + return false + } + const activeElement = document.activeElement + if (activeElement instanceof HTMLInputElement) { + activeElement.select() + } + return true + }, + COMMAND_PRIORITY_LOW, + ) + }, [editor]) + + return null +} diff --git a/test/database/up-down-migration/migrations/20250528_153134.ts b/test/database/up-down-migration/migrations/20250528_153134.ts index 086047bb6..5409567ee 100644 --- a/test/database/up-down-migration/migrations/20250528_153134.ts +++ b/test/database/up-down-migration/migrations/20250528_153134.ts @@ -1,4 +1,4 @@ -import type { MigrateDownArgs, MigrateUpArgs} from '@payloadcms/db-postgres'; +import type { MigrateDownArgs, MigrateUpArgs } from '@payloadcms/db-postgres' import { sql } from '@payloadcms/db-postgres' diff --git a/test/lexical/collections/_LexicalFullyFeatured/e2e.spec.ts b/test/lexical/collections/_LexicalFullyFeatured/e2e.spec.ts index 7881f37a4..9e42481b7 100644 --- a/test/lexical/collections/_LexicalFullyFeatured/e2e.spec.ts +++ b/test/lexical/collections/_LexicalFullyFeatured/e2e.spec.ts @@ -62,6 +62,24 @@ describe('Lexical Fully Featured', () => { const paragraph = lexical.editor.locator('> p') await expect(paragraph).toHaveText('') }) + + test('ControlOrMeta+A inside input should select all the text inside the input', async ({ + page, + }) => { + const lexical = new LexicalHelpers(page) + await lexical.editor.first().focus() + await page.keyboard.type('Hello') + await page.keyboard.press('Enter') + await lexical.slashCommand('block') + await page.locator('#field-someText').first().focus() + await page.keyboard.type('World') + await page.keyboard.press('ControlOrMeta+A') + await page.keyboard.press('Backspace') + const paragraph = lexical.editor.locator('> p').first() + await expect(paragraph).toHaveText('Hello') + await expect(page.getByText('World')).toHaveCount(0) + }) + test('text state feature', async ({ page }) => { await page.keyboard.type('Hello') await page.keyboard.press('ControlOrMeta+A') diff --git a/tsconfig.base.json b/tsconfig.base.json index 451c9cfda..8d0bb793b 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -31,7 +31,7 @@ } ], "paths": { - "@payload-config": ["./test/query-presets/config.ts"], + "@payload-config": ["./test/_community/config.ts"], "@payloadcms/admin-bar": ["./packages/admin-bar/src"], "@payloadcms/live-preview": ["./packages/live-preview/src"], "@payloadcms/live-preview-react": ["./packages/live-preview-react/src/index.ts"],