Skip to content

Commit

Permalink
feat: add support for bar menu (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sachin-chaurasiya authored Dec 9, 2023
1 parent fb90490 commit be64c59
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 7 deletions.
19 changes: 17 additions & 2 deletions lib/components/BlockEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { extensions as defaultExtensions } from './extension';
import { EditorProps } from '@tiptap/pm/view';
import { FC } from 'react';
import BubbleMenu from '../Menu/BubbleMenu';
import BarMenu from '../Menu/BarMenu';

export interface BlockEditorProps {
onContentChange?: (content: string) => void;
Expand All @@ -13,6 +14,7 @@ export interface BlockEditorProps {
autoFocus?: boolean;
extensions?: Extension[];
editorProps?: EditorProps;
menuType?: 'bubble' | 'bar';
}

export const BlockEditor: FC<BlockEditorProps> = ({
Expand All @@ -23,6 +25,7 @@ export const BlockEditor: FC<BlockEditorProps> = ({
extensions,
onContentChange,
readOnly,
menuType = 'bubble',
}) => {
const editor = useEditor({
extensions: [...defaultExtensions, ...(extensions ?? [])],
Expand All @@ -48,8 +51,20 @@ export const BlockEditor: FC<BlockEditorProps> = ({
className={`block-editor-wrapper ${className}`}
id="block-editor-wrapper"
>
<EditorContent editor={editor} />
{editor && <BubbleMenu editor={editor} />}
{menuType === 'bar' && (
<div className="m-[40px] rounded-lg border min-h-[300px]">
{editor && <BarMenu editor={editor} />}
<div className="h-full w-full p-[16px]">
<EditorContent editor={editor} />
</div>
</div>
)}
{menuType === 'bubble' && (
<>
<EditorContent editor={editor} />
{editor && <BubbleMenu editor={editor} />}
</>
)}
</div>
);
};
126 changes: 126 additions & 0 deletions lib/components/Menu/BarMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Editor } from '@tiptap/react';
import { FC, Fragment } from 'react';

export interface BarMenuProps {
editor: Editor;
}

const BarMenu: FC<BarMenuProps> = ({ editor }) => {
const Formats = [
[
{
name: 'bold',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/bold.svg',
command: () => editor.chain().focus().toggleBold().run(),
isActive: () => editor.isActive('bold'),
},
{
name: 'italic',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/italic.svg',
command: () => editor.chain().focus().toggleItalic().run(),
isActive: () => editor.isActive('italic'),
},
{
name: 'strike',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/text-strike.svg',
command: () => editor.chain().focus().toggleStrike().run(),
isActive: () => editor.isActive('strike'),
},
],
[
{
name: 'inline-code',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/inline-code.svg',
command: () => editor.chain().focus().toggleCode().run(),
isActive: () => editor.isActive('code'),
},
{
name: 'highlight',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/highlight.svg',
command: () => editor.chain().focus().run(),
isActive: () => false,
disabled: true,
},
],
[
{
name: 'unordered-list',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/unordered-list.svg',
command: () => editor.chain().focus().toggleBulletList().run(),
isActive: () => editor.isActive('bulletList'),
},
{
name: 'ordered-list',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/ordered-list.svg',
command: () => editor.chain().focus().toggleOrderedList().run(),
isActive: () => editor.isActive('orderedList'),
},
],
[
{
name: 'link',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/link.svg',
command: () => editor.chain().focus().run(),
isActive: () => false,
disabled: true,
},
{
name: 'image',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/image.svg',
command: () => editor.chain().focus().run(),
isActive: () => false,
disabled: true,
},
{
name: 'code-block',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/code-block.svg',
command: () => editor.chain().focus().toggleCodeBlock().run(),
isActive: () => editor.isActive('codeBlock'),
},
{
name: 'block-quote',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/block-quote.svg',
command: () => editor.chain().focus().toggleBlockquote().run(),
isActive: () => editor.isActive('blockquote'),
},
{
name: 'horizontal-line',
icon: 'https://raw.githubusercontent.com/Sachin-chaurasiya/rich-text-editor-icons/main/icons/horizontal-line.svg',
command: () => editor.chain().focus().setHorizontalRule().run(),
isActive: () => false,
},
],
];

return (
<div className="flex flex-row gap-2 border-b p-[8px]">
{Formats.map((format, index) => {
return (
<Fragment key={`format-group-${index}`}>
<div className="flex">
{format.map((item) => {
return (
<button
disabled={item?.disabled}
key={item.name}
className={`rounded-md ${
item.isActive() ? 'bg-gray-100' : ''
} ${
item?.disabled ? 'cursor-not-allowed bg-opacity-50' : ''
}}`}
onClick={item.command}
>
<img src={item.icon} alt={item.name} />
</button>
);
})}
</div>
{index !== Formats.length - 1 && <div className="border-l"></div>}
</Fragment>
);
})}
</div>
);
};

export default BarMenu;
6 changes: 1 addition & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { BlockEditor } from '../dist/main';

function App() {
return (
<>
<BlockEditor />
</>
);
return <BlockEditor menuType="bar" />;
}

export default App;

0 comments on commit be64c59

Please sign in to comment.