Skip to content

Commit

Permalink
[PE-155] chore: floating toolbar for pages (#6482)
Browse files Browse the repository at this point in the history
* chore: add floating toolbar to pages

* fix: locked page toolbar
  • Loading branch information
aaryan610 authored Jan 28, 2025
1 parent 421839e commit b698f44
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
const {
onTransaction,
aiHandler,
bubbleMenuEnabled = true,
containerClassName,
disabledExtensions,
displayConfig = DEFAULT_DISPLAY_CONFIG,
Expand Down Expand Up @@ -75,8 +76,9 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {

return (
<PageRenderer
displayConfig={displayConfig}
aiHandler={aiHandler}
bubbleMenuEnabled={bubbleMenuEnabled}
displayConfig={displayConfig}
editor={editor}
editorContainerClassName={editorContainerClassNames}
id={id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {

return (
<PageRenderer
bubbleMenuEnabled={false}
displayConfig={displayConfig}
editor={editor}
editorContainerClassName={editorContainerClassName}
Expand Down
3 changes: 2 additions & 1 deletion packages/editor/src/core/types/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions web/core/components/pages/dropdowns/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { TPageInstance } from "@/store/pages/base-page";

export type TPageActions =
| "full-screen"
| "sticky-toolbar"
| "copy-markdown"
| "toggle-lock"
| "toggle-access"
Expand Down
28 changes: 25 additions & 3 deletions web/core/components/pages/editor/header/options-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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: () => {
Expand Down Expand Up @@ -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 (
Expand All @@ -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",
Expand Down
6 changes: 4 additions & 2 deletions web/core/components/pages/editor/header/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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>
Expand Down
28 changes: 27 additions & 1 deletion web/core/hooks/use-page-filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => {
Expand All @@ -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]
Expand Down Expand Up @@ -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,
Expand All @@ -86,5 +110,7 @@ export const usePageFilters = () => {
handleFontStyle,
isFullWidth,
handleFullWidth,
isStickyToolbarEnabled,
handleStickyToolbar,
};
};

0 comments on commit b698f44

Please sign in to comment.