feat(editor): show doc title in page block (#9975)

Close [BS-2392](https://linear.app/affine-design/issue/BS-2392/page-block-需要显示文章title)

### What Changes
- Add `<doc-title>` to edgeless page block (a.k.a the first page visible note block)
- Refactors:
  - Move `<doc-title>` to `@blocksuite/affine-component`, but you can aslo import it from `@blocksuite/preset`
  - Extract `<edgeless-note-mask>` and `<edgeless-note-background>` from `<affine-edgeless-note>` to a seperate file
  - Rewrite styles of `<affine-edgeless-note>` with `@vanilla-extract/css`

https://github.com/user-attachments/assets/a0c03239-803e-4bfa-b30e-33b919213b12
This commit is contained in:
L-Sun
2025-02-06 21:18:27 +00:00
parent 41107eafae
commit 891d9df0b1
33 changed files with 626 additions and 337 deletions

View File

@@ -11,12 +11,15 @@ import {
} from '@affine-test/kit/utils/editor';
import {
pasteByKeyboard,
pressBackspace,
pressEnter,
selectAllByKeyboard,
undoByKeyboard,
} from '@affine-test/kit/utils/keyboard';
import { openHomePage } from '@affine-test/kit/utils/load-page';
import {
clickNewPageButton,
type,
waitForEditorLoad,
} from '@affine-test/kit/utils/page-logic';
import { expect, type Page } from '@playwright/test';
@@ -36,7 +39,8 @@ test.beforeEach(async ({ page }) => {
await container.click();
});
test.describe('edgeless page header toolbar', () => {
// the first note block is called page block
test.describe('edgeless page block', () => {
const locateHeaderToolbar = (page: Page) =>
page.getByTestId('edgeless-page-block-header');
@@ -77,7 +81,7 @@ test.describe('edgeless page header toolbar', () => {
expect(newNoteBox2).toEqual(noteBox);
});
test('page title should be displayed when page block is collapsed and hidden when page block is not collapsed', async ({
test('page title in toolbar should be displayed when page block is collapsed and hidden when page block is not collapsed', async ({
page,
}) => {
const toolbar = locateHeaderToolbar(page);
@@ -143,6 +147,45 @@ test.describe('edgeless page header toolbar', () => {
await expect(toolbar).toBeVisible();
await expect(infoButton).toBeHidden();
});
test('page title should show in note when page block is not collapsed', async ({
page,
}) => {
const note = page.locator('affine-edgeless-note');
const docTitle = note.locator('doc-title');
await expect(docTitle).toBeVisible();
await expect(docTitle).toHaveText(title);
await note.dblclick();
await docTitle.click();
// clear the title
await selectAllByKeyboard(page);
await pressBackspace(page);
await expect(docTitle).toHaveText('');
// type new title
await type(page, 'New Title');
await expect(docTitle).toHaveText('New Title');
// cursor could move between doc title and note content
await page.keyboard.press('ArrowDown');
await type(page, 'xx');
const paragraphs = note.locator('affine-paragraph v-line');
const numParagraphs = await paragraphs.count();
await expect(paragraphs.first()).toHaveText('xxHello');
await page.keyboard.press('ArrowUp');
await type(page, 'yy');
await expect(docTitle).toHaveText('yyNew Title');
await pressEnter(page);
await expect(docTitle).toHaveText('yy');
await expect(paragraphs).toHaveCount(numParagraphs + 1);
await expect(paragraphs.nth(0)).toHaveText('New Title');
await expect(paragraphs.nth(1)).toHaveText('xxHello');
});
});
test.describe('edgeless note element toolbar', () => {