♻️(frontend) better handling css doc states
We simplify the way we handle different doc states (deleted / readonly) in the CSS, we avoid props drilling and are more component focused.
This commit is contained in:
@@ -119,6 +119,10 @@ test.describe('Doc Trashbin', () => {
|
||||
await row.getByText(subDocName).click();
|
||||
await verifyDocName(page, subDocName);
|
||||
|
||||
await expect(
|
||||
page.locator('.--docs--editor-container.--docs--doc-deleted'),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(page.getByLabel('Alert deleted document')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Share' })).toBeDisabled();
|
||||
await expect(page.locator('.bn-editor')).toHaveAttribute(
|
||||
|
||||
@@ -260,6 +260,10 @@ test.describe('Doc Visibility: Public', () => {
|
||||
await expect(card).toBeVisible();
|
||||
await expect(card.getByText('Reader')).toBeVisible();
|
||||
|
||||
await expect(
|
||||
otherPage.locator('.--docs--editor-container.--docs--doc-readonly'),
|
||||
).toBeVisible();
|
||||
|
||||
const otherEditor = await getEditor({ page: otherPage });
|
||||
await expect(otherEditor).toHaveAttribute('contenteditable', 'false');
|
||||
await expect(otherEditor.getByText('Hello Public Viewonly')).toBeVisible();
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
useUploadStatus,
|
||||
} from '../hook';
|
||||
import { useEditorStore } from '../stores';
|
||||
import { cssEditor } from '../styles';
|
||||
import { DocsBlockNoteEditor } from '../types';
|
||||
import { randomColor } from '../utils';
|
||||
|
||||
@@ -169,7 +170,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
|
||||
}, [setEditor, editor]);
|
||||
|
||||
return (
|
||||
<Box ref={refEditorContainer}>
|
||||
<Box ref={refEditorContainer} $css={cssEditor}>
|
||||
{errorAttachment && (
|
||||
<Box $margin={{ bottom: 'big', top: 'none', horizontal: 'large' }}>
|
||||
<TextErrors
|
||||
@@ -225,12 +226,14 @@ export const BlockNoteReader = ({ initialContent }: BlockNoteReaderProps) => {
|
||||
useHeadings(editor);
|
||||
|
||||
return (
|
||||
<BlockNoteView
|
||||
editor={editor}
|
||||
editable={false}
|
||||
theme="light"
|
||||
formattingToolbar={false}
|
||||
slashMenu={false}
|
||||
/>
|
||||
<Box $css={cssEditor}>
|
||||
<BlockNoteView
|
||||
editor={editor}
|
||||
editable={false}
|
||||
theme="light"
|
||||
formattingToolbar={false}
|
||||
slashMenu={false}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import clsx from 'clsx';
|
||||
import { useEffect } from 'react';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
@@ -12,8 +13,6 @@ import { TableContent } from '@/docs/doc-table-content/';
|
||||
import { useSkeletonStore } from '@/features/skeletons';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { cssEditor } from '../styles';
|
||||
|
||||
import { BlockNoteEditor, BlockNoteReader } from './BlockNoteEditor';
|
||||
|
||||
interface DocEditorContainerProps {
|
||||
@@ -55,10 +54,13 @@ export const DocEditorContainer = ({
|
||||
>
|
||||
<Box $css="flex:1;" $position="relative" $width="100%">
|
||||
<Box
|
||||
$padding={{ top: 'md' }}
|
||||
$padding={{ top: 'md', bottom: '2rem' }}
|
||||
$background="white"
|
||||
$css={cssEditor(readOnly, isDeletedDoc)}
|
||||
className="--docs--editor-container"
|
||||
className={clsx('--docs--editor-container', {
|
||||
'--docs--doc-readonly': readOnly,
|
||||
'--docs--doc-deleted': isDeletedDoc,
|
||||
})}
|
||||
$height="100%"
|
||||
>
|
||||
{docEditor}
|
||||
</Box>
|
||||
@@ -77,7 +79,9 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const { provider, isReady } = useProviderStore();
|
||||
const { isEditable, isLoading } = useIsCollaborativeEditable(doc);
|
||||
const readOnly = !doc.abilities.partial_update || !isEditable || isLoading;
|
||||
const isDeletedDoc = !!doc.deleted_at;
|
||||
const readOnly =
|
||||
!doc.abilities.partial_update || !isEditable || isLoading || isDeletedDoc;
|
||||
const { setIsSkeletonVisible } = useSkeletonStore();
|
||||
const isProviderReady = isReady && provider;
|
||||
|
||||
@@ -117,7 +121,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
|
||||
<BlockNoteEditor doc={doc} provider={provider} />
|
||||
)
|
||||
}
|
||||
isDeletedDoc={!!doc.deleted_at}
|
||||
isDeletedDoc={isDeletedDoc}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -89,6 +89,10 @@ const LinkSelected = ({ url, title }: LinkSelectedProps) => {
|
||||
background-color: ${colorsTokens['greyscale-100']};
|
||||
}
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
|
||||
.--docs--doc-deleted & {
|
||||
pointer-events: none;
|
||||
}
|
||||
`}
|
||||
>
|
||||
{emoji ? (
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { css } from 'styled-components';
|
||||
|
||||
export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css`
|
||||
export const cssEditor = css`
|
||||
&,
|
||||
& > .bn-container,
|
||||
& .ProseMirror {
|
||||
height: 100%;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
& .ProseMirror {
|
||||
/**
|
||||
* WCAG Accessibility contrast fixes for BlockNote editor
|
||||
*/
|
||||
@@ -131,13 +132,6 @@ export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css`
|
||||
.bn-block-outer:not([data-prev-depth-changed]):before {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
${isDeletedDoc &&
|
||||
`
|
||||
.node-interlinkingLinkInline button {
|
||||
pointer-events: none;
|
||||
}
|
||||
`}
|
||||
}
|
||||
|
||||
& .bn-editor {
|
||||
@@ -187,8 +181,10 @@ export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css`
|
||||
}
|
||||
|
||||
@media screen and (width <= 560px) {
|
||||
.--docs--doc-readonly & .bn-editor {
|
||||
padding-left: 10px;
|
||||
}
|
||||
& .bn-editor {
|
||||
${readonly && `padding-left: 10px;`}
|
||||
padding-right: 10px;
|
||||
}
|
||||
.bn-side-menu[data-block-type='heading'][data-level='1'] {
|
||||
|
||||
Reference in New Issue
Block a user