Skip to content

Commit

Permalink
feat: add EditorStickyToolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
2wheeh committed May 4, 2024
1 parent 38327ed commit 765dba6
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ui/src/app/(board)/review/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import UserChip from '@/components/auth/client/user-chip';
import Text from '@/components/common/server/text';
import Time from '@/components/common/server/time';
import { EditorStickyToolbar } from '@/components/review/client/editor-sticky-toolbar';
import ReviewTitle from '@/components/review/client/review-title';
import { ViewerHeader } from '@/components/review/client/viewer-header';
import { Viewer } from '@/components/review/server/viewer';
Expand All @@ -20,6 +21,7 @@ export default async function Page({ params }: { params: { id: string } }) {
<ReviewProvider prepopulated={{ movieName: review.movieName, title: review.title }}>
<main className="container mx-auto flex max-w-5xl flex-col items-center">
<ViewerHeader />
<EditorStickyToolbar />

<section className="w-full p-4">
<div className="my-2 flex items-center gap-1">
Expand Down
2 changes: 2 additions & 0 deletions ui/src/app/(board)/review/write/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { BoardHeader } from '@/components/common/server/board-header';
import Text from '@/components/common/server/text';
import Time from '@/components/common/server/time';
import { CreateReviewButton } from '@/components/review/client/create-review-button';
import { EditorStickyToolbar } from '@/components/review/client/editor-sticky-toolbar';
import ReviewTitle from '@/components/review/client/review-title';

import { EditorRefProvider } from '@/context/editor/editor-ref-context';
Expand Down Expand Up @@ -35,6 +36,7 @@ export default function Page() {
<ReviewProvider>
<main className="container mx-auto flex max-w-5xl flex-col items-center">
<EditorHeader />
<EditorStickyToolbar />

<section className="w-full p-4">
<div className="my-2 flex items-center gap-1">
Expand Down
87 changes: 87 additions & 0 deletions ui/src/components/review/client/editor-sticky-toolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
'use client';

import { ArrowsUpDownIcon } from '@heroicons/react/24/outline';
import clsx from 'clsx';
import { BLUR_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical';
import { useEffect, useState } from 'react';

import { IconButton } from '@/components/common/client/icon-button';
import { BlockTypeActions } from '@/components/review/client/block-type-actions';
import { HistoryActions } from '@/components/review/client/history-actions';
import { TextFormatActions } from '@/components/review/client/text-format-actions';

import { useEditable } from '@/context/editor/editable-context';
import { useEditorRef } from '@/context/editor/editor-ref-context';

import { useStickyIOS } from '@/hooks/common/use-sticky-ios';

export function EditorStickyToolbar() {
const { isEditable } = useEditable() ?? {};

if (isEditable === false) {
return null;
}

return <EditorToolbarInner />;
}

function EditorToolbarInner() {
const { handleBlur, stickyRef, wrapperRef } = useStickyIOS();

const { editorRef } = useEditorRef() ?? {};

const editor = editorRef?.current;

useEffect(() => {
if (!editor) {
return;
}

return editor.registerCommand(
BLUR_COMMAND,
() => {
handleBlur();
return false;
},
COMMAND_PRIORITY_LOW
);
}, [editor, handleBlur]);

const [barType, setBarType] = useState<'text' | 'block'>('text');

return (
<div ref={wrapperRef} className="sticky top-[67px] z-20 h-12 w-full bg-white backface-hidden">
<div
ref={stickyRef}
className="absolute left-0 right-0 p-2 space-x-2 flex border-b z-20 bg-white"
>
<HistoryActions editor={editor} />

<IconButton
onClick={() => setBarType((prev) => (prev === 'text' ? 'block' : 'text'))}
icon={<ArrowsUpDownIcon className="w-5" />}
/>

<div className="relative w-full">
<div
className={clsx('absolute top-0 transition-all duration-500 w-full', {
'top-0 -translate-y-1/2 opacity-0 pointer-events-none': barType === 'block',
'top-0': barType === 'text',
})}
>
<TextFormatActions editor={editor} />
</div>

<div
className={clsx('absolute top-0 transition-all duration-500 w-full', {
'top-0 -translate-y-1/2 opacity-0 pointer-events-none': barType === 'text',
'top-0': barType === 'block',
})}
>
<BlockTypeActions editor={editor} />
</div>
</div>
</div>
</div>
);
}

0 comments on commit 765dba6

Please sign in to comment.