[PE-155] chore: floating toolbar for pages (#6482)
* chore: add floating toolbar to pages * fix: locked page toolbar
This commit is contained in:
parent
421839ec51
commit
b698f44500
8 changed files with 67 additions and 10 deletions
|
|
@ -16,6 +16,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
|||
const {
|
||||
onTransaction,
|
||||
aiHandler,
|
||||
bubbleMenuEnabled = true,
|
||||
containerClassName,
|
||||
disabledExtensions,
|
||||
displayConfig = DEFAULT_DISPLAY_CONFIG,
|
||||
|
|
@ -75,8 +76,9 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
|||
|
||||
return (
|
||||
<PageRenderer
|
||||
displayConfig={displayConfig}
|
||||
aiHandler={aiHandler}
|
||||
bubbleMenuEnabled={bubbleMenuEnabled}
|
||||
displayConfig={displayConfig}
|
||||
editor={editor}
|
||||
editorContainerClassName={editorContainerClassNames}
|
||||
id={id}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,13 @@ import { Editor, ReactRenderer } from "@tiptap/react";
|
|||
// components
|
||||
import { EditorContainer, EditorContentWrapper } from "@/components/editors";
|
||||
import { LinkView, LinkViewProps } from "@/components/links";
|
||||
import { AIFeaturesMenu, BlockMenu } from "@/components/menus";
|
||||
import { AIFeaturesMenu, BlockMenu, EditorBubbleMenu } from "@/components/menus";
|
||||
// types
|
||||
import { TAIHandler, TDisplayConfig } from "@/types";
|
||||
|
||||
type IPageRenderer = {
|
||||
aiHandler?: TAIHandler;
|
||||
bubbleMenuEnabled: boolean;
|
||||
displayConfig: TDisplayConfig;
|
||||
editor: Editor;
|
||||
editorContainerClassName: string;
|
||||
|
|
@ -29,7 +30,7 @@ type IPageRenderer = {
|
|||
};
|
||||
|
||||
export const PageRenderer = (props: IPageRenderer) => {
|
||||
const { aiHandler, displayConfig, editor, editorContainerClassName, id, tabIndex } = props;
|
||||
const { aiHandler, bubbleMenuEnabled, displayConfig, editor, editorContainerClassName, id, tabIndex } = props;
|
||||
// states
|
||||
const [linkViewProps, setLinkViewProps] = useState<LinkViewProps>();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
|
@ -141,6 +142,7 @@ export const PageRenderer = (props: IPageRenderer) => {
|
|||
<EditorContentWrapper editor={editor} id={id} tabIndex={tabIndex} />
|
||||
{editor.isEditable && (
|
||||
<div>
|
||||
{bubbleMenuEnabled && <EditorBubbleMenu editor={editor} />}
|
||||
<BlockMenu editor={editor} />
|
||||
<AIFeaturesMenu menu={aiHandler?.menu} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
|
|||
|
||||
return (
|
||||
<PageRenderer
|
||||
bubbleMenuEnabled={false}
|
||||
displayConfig={displayConfig}
|
||||
editor={editor}
|
||||
editorContainerClassName={editorContainerClassName}
|
||||
|
|
|
|||
|
|
@ -138,8 +138,9 @@ export interface IRichTextEditor extends IEditorProps {
|
|||
|
||||
export interface ICollaborativeDocumentEditor
|
||||
extends Omit<IEditorProps, "initialValue" | "onChange" | "onEnterKeyPress" | "value"> {
|
||||
editable: boolean;
|
||||
aiHandler?: TAIHandler;
|
||||
bubbleMenuEnabled?: boolean;
|
||||
editable: boolean;
|
||||
embedHandler: TEmbedConfig;
|
||||
handleEditorReady?: (value: boolean) => void;
|
||||
id: string;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import { TPageInstance } from "@/store/pages/base-page";
|
|||
|
||||
export type TPageActions =
|
||||
| "full-screen"
|
||||
| "sticky-toolbar"
|
||||
| "copy-markdown"
|
||||
| "toggle-lock"
|
||||
| "toggle-access"
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
|||
// router
|
||||
const router = useRouter();
|
||||
// store values
|
||||
const { name } = page;
|
||||
const { name, isContentEditable } = page;
|
||||
// page filters
|
||||
const { isFullWidth, handleFullWidth } = usePageFilters();
|
||||
const { isFullWidth, handleFullWidth, isStickyToolbarEnabled, handleStickyToolbar } = usePageFilters();
|
||||
// update query params
|
||||
const { updateQueryParams } = useQueryParams();
|
||||
// menu items list
|
||||
|
|
@ -49,6 +49,18 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
|||
),
|
||||
className: "flex items-center justify-between gap-2",
|
||||
},
|
||||
{
|
||||
key: "sticky-toolbar",
|
||||
action: () => handleStickyToolbar(!isStickyToolbarEnabled),
|
||||
customContent: (
|
||||
<>
|
||||
Sticky toolbar
|
||||
<ToggleSwitch value={isStickyToolbarEnabled} onChange={() => {}} />
|
||||
</>
|
||||
),
|
||||
className: "flex items-center justify-between gap-2",
|
||||
shouldRender: isContentEditable,
|
||||
},
|
||||
{
|
||||
key: "copy-markdown",
|
||||
action: () => {
|
||||
|
|
@ -86,7 +98,16 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
|||
shouldRender: true,
|
||||
},
|
||||
],
|
||||
[editorRef, handleFullWidth, isFullWidth, router, updateQueryParams]
|
||||
[
|
||||
editorRef,
|
||||
handleFullWidth,
|
||||
handleStickyToolbar,
|
||||
isContentEditable,
|
||||
isFullWidth,
|
||||
isStickyToolbarEnabled,
|
||||
router,
|
||||
updateQueryParams,
|
||||
]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
@ -102,6 +123,7 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
|||
extraOptions={EXTRA_MENU_OPTIONS}
|
||||
optionsOrder={[
|
||||
"full-screen",
|
||||
"sticky-toolbar",
|
||||
"copy-link",
|
||||
"make-a-copy",
|
||||
"move",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export const PageEditorHeaderRoot: React.FC<Props> = observer((props) => {
|
|||
// derived values
|
||||
const { isContentEditable } = page;
|
||||
// page filters
|
||||
const { isFullWidth } = usePageFilters();
|
||||
const { isFullWidth, isStickyToolbarEnabled } = usePageFilters();
|
||||
// derived values
|
||||
const resolvedEditorRef = editorRef.current;
|
||||
|
||||
|
|
@ -48,7 +48,9 @@ export const PageEditorHeaderRoot: React.FC<Props> = observer((props) => {
|
|||
/>
|
||||
</div>
|
||||
)}
|
||||
{editorReady && isContentEditable && editorRef.current && <PageToolbar editorRef={editorRef?.current} />}
|
||||
{isStickyToolbarEnabled && editorReady && isContentEditable && editorRef.current && (
|
||||
<PageToolbar editorRef={editorRef?.current} />
|
||||
)}
|
||||
</Header.LeftItem>
|
||||
<PageExtraOptions editorRef={resolvedEditorRef} page={page} />
|
||||
</Header>
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@ export type TPagesPersonalizationConfig = {
|
|||
full_width: boolean;
|
||||
font_size: TEditorFontSize;
|
||||
font_style: TEditorFontStyle;
|
||||
sticky_toolbar: boolean;
|
||||
};
|
||||
|
||||
const DEFAULT_PERSONALIZATION_VALUES: TPagesPersonalizationConfig = {
|
||||
full_width: false,
|
||||
font_size: "large-font",
|
||||
font_style: "sans-serif",
|
||||
sticky_toolbar: true,
|
||||
};
|
||||
|
||||
export const usePageFilters = () => {
|
||||
|
|
@ -23,7 +25,17 @@ export const usePageFilters = () => {
|
|||
DEFAULT_PERSONALIZATION_VALUES
|
||||
);
|
||||
// stored values
|
||||
const isFullWidth = useMemo(() => !!pagesConfig?.full_width, [pagesConfig?.full_width]);
|
||||
const isFullWidth = useMemo(
|
||||
() => (pagesConfig?.full_width === undefined ? DEFAULT_PERSONALIZATION_VALUES.full_width : pagesConfig?.full_width),
|
||||
[pagesConfig?.full_width]
|
||||
);
|
||||
const isStickyToolbarEnabled = useMemo(
|
||||
() =>
|
||||
pagesConfig?.sticky_toolbar === undefined
|
||||
? DEFAULT_PERSONALIZATION_VALUES.sticky_toolbar
|
||||
: pagesConfig?.sticky_toolbar,
|
||||
[pagesConfig?.sticky_toolbar]
|
||||
);
|
||||
const fontSize = useMemo(
|
||||
() => pagesConfig?.font_size ?? DEFAULT_PERSONALIZATION_VALUES.font_size,
|
||||
[pagesConfig?.font_size]
|
||||
|
|
@ -78,6 +90,18 @@ export const usePageFilters = () => {
|
|||
},
|
||||
[handleUpdateConfig]
|
||||
);
|
||||
/**
|
||||
* @description action to update full_width value
|
||||
* @param {boolean} value
|
||||
*/
|
||||
const handleStickyToolbar = useCallback(
|
||||
(value: boolean) => {
|
||||
handleUpdateConfig({
|
||||
sticky_toolbar: value,
|
||||
});
|
||||
},
|
||||
[handleUpdateConfig]
|
||||
);
|
||||
|
||||
return {
|
||||
fontSize,
|
||||
|
|
@ -86,5 +110,7 @@ export const usePageFilters = () => {
|
|||
handleFontStyle,
|
||||
isFullWidth,
|
||||
handleFullWidth,
|
||||
isStickyToolbarEnabled,
|
||||
handleStickyToolbar,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue