💄(frontend) improve ui table of contents

- keep correctly the text on the left side
- improve accuracy highlightment heading when scrolling
- display full heading text when text transform is applied
- fix typo
This commit is contained in:
Anthony LC
2024-09-17 17:35:24 +02:00
committed by Anthony LC
parent 5bd78b8068
commit b37acf3138
5 changed files with 47 additions and 27 deletions

View File

@@ -20,7 +20,7 @@ test.describe('Doc Table Content', () => {
await page.getByLabel('Open the document options').click();
await page
.getByRole('button', {
name: 'Table of content',
name: 'Table of contents',
})
.click();
@@ -30,6 +30,8 @@ test.describe('Doc Table Content', () => {
await editor.locator('.bn-block-outer').last().fill('/');
await page.getByText('Heading 1').click();
await page.keyboard.type('Hello World');
await editor.getByText('Hello').dblclick();
await page.getByRole('button', { name: 'Strike' }).click();
await page.locator('.bn-block-outer').last().click();
@@ -40,7 +42,7 @@ test.describe('Doc Table Content', () => {
await editor.locator('.bn-block-outer').last().fill('/');
await page.getByText('Heading 2').click();
await page.keyboard.type('Super World');
await page.keyboard.type('Super World', { delay: 100 });
await page.locator('.bn-block-outer').last().click();
@@ -58,15 +60,15 @@ test.describe('Doc Table Content', () => {
const another = panel.getByText('Another World');
await expect(hello).toBeVisible();
await expect(hello).toHaveCSS('font-size', '19.2px');
await expect(hello).toHaveCSS('font-size', /19/);
await expect(hello).toHaveAttribute('aria-selected', 'true');
await expect(superW).toBeVisible();
await expect(superW).toHaveCSS('font-size', '16px');
await expect(superW).toHaveCSS('font-size', /16/);
await expect(superW).toHaveAttribute('aria-selected', 'false');
await expect(another).toBeVisible();
await expect(another).toHaveCSS('font-size', '12.8px');
await expect(another).toHaveCSS('font-size', /12/);
await expect(another).toHaveAttribute('aria-selected', 'false');
await hello.click();

View File

@@ -36,10 +36,10 @@ export const Panel = ({
$width="100%"
$maxWidth="20rem"
$position="sticky"
$maxHeight="96vh"
$maxHeight="99vh"
$height="100%"
$css={`
top: 2vh;
top: 0vh;
transition: ${transition};
${
!isOpen &&

View File

@@ -91,7 +91,7 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
icon={<span className="material-icons">summarize</span>}
size="small"
>
<Text $theme="primary">{t('Table of content')}</Text>
<Text $theme="primary">{t('Table of contents')}</Text>
</Button>
<Button
onClick={() => {

View File

@@ -46,6 +46,7 @@ export const Heading = ({
block: 'start',
});
}}
$css="text-align: left;"
>
<Text
$theme="primary"

View File

@@ -10,11 +10,28 @@ import { useDocTableContentStore } from '../stores';
import { Heading } from './Heading';
const recursiveTextContent = (content: HeadingBlock['content']): string => {
if (!content) {
return '';
}
return content.reduce((acc, content) => {
if (content.type === 'text') {
return acc + content.text;
} else if (content.type === 'link') {
return acc + recursiveTextContent(content.content);
}
return acc;
}, '');
};
type HeadingBlock = {
id: string;
type: string;
text: string;
content: HeadingBlock[];
contentText: string;
props: {
level: number;
};
@@ -31,9 +48,14 @@ export const TableContent = ({ doc }: TableContentProps) => {
const editor = docsStore?.[doc.id]?.editor;
const headingFiltering = useCallback(
() =>
editor?.document.filter(
(block) => block.type === 'heading',
) as unknown as HeadingBlock[],
editor?.document
.filter((block) => block.type === 'heading')
.map((block) => ({
...block,
contentText: recursiveTextContent(
block.content as unknown as HeadingBlock['content'],
),
})) as unknown as HeadingBlock[],
[editor?.document],
);
@@ -71,7 +93,7 @@ export const TableContent = ({ doc }: TableContentProps) => {
for (const heading of headings) {
const elHeading = document.body.querySelector(
`.bn-block-outer[data-id="${heading.id}"]`,
`.bn-block-outer[data-id="${heading.id}"] [data-content-type="heading"]:first-child`,
);
if (!elHeading) {
@@ -121,21 +143,16 @@ export const TableContent = ({ doc }: TableContentProps) => {
<Panel setIsPanelOpen={setClosePanel}>
<Box $padding="small" $maxHeight="95%">
<Box $overflow="auto">
{headings?.map((heading) => {
const content = heading.content?.[0];
const text = content?.type === 'text' ? content.text : '';
return (
<Heading
editor={editor}
headingId={heading.id}
level={heading.props.level}
text={text}
key={heading.id}
isHighlight={headingIdHighlight === heading.id}
/>
);
})}
{headings?.map((heading) => (
<Heading
editor={editor}
headingId={heading.id}
level={heading.props.level}
text={heading.contentText}
key={heading.id}
isHighlight={headingIdHighlight === heading.id}
/>
))}
</Box>
<Box
$height="1px"