feat: added code,links, & styling the editor

This commit is contained in:
MTG2000
2022-04-27 11:01:42 +03:00
parent 2c615bcf9f
commit 4957dad00b
7 changed files with 1834 additions and 174 deletions

1924
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,7 @@
"lodash.throttle": "^4.1.1",
"marked": "^4.0.14",
"nexus": "^1.3.0",
"node-sass": "^7.0.1",
"prisma": "^3.12.0",
"react": "^18.0.0",
"react-confetti": "^6.0.1",

View File

@@ -13,7 +13,7 @@ const Template: ComponentStory<typeof TextEditor> = (args) => <TextEditor {...ar
export const Default = Template.bind({});
Default.args = {
placeholder: "Start writing something in markdown"
}

View File

@@ -1,6 +1,8 @@
import 'remirror/styles/all.css';
import styles from './styles.module.scss'
import javascript from 'refractor/lang/javascript';
import typescript from 'refractor/lang/typescript';
import {
BlockquoteExtension,
BoldExtension,
@@ -9,6 +11,7 @@ import {
CodeExtension,
HardBreakExtension,
HeadingExtension,
ImageExtension,
ItalicExtension,
LinkExtension,
ListItemExtension,
@@ -23,7 +26,7 @@ import {
} from 'remirror/extensions';
import { ExtensionPriority } from 'remirror';
import { EditorComponent, Remirror, useRemirror } from '@remirror/react';
import { useCallback } from 'react';
import { useCallback, useMemo } from 'react';
import Toolbar from './Toolbar/Toolbar';
@@ -32,11 +35,21 @@ interface Props {
initialContent?: string;
}
export default function TextEditor({ placeholder, initialContent = 'Hello everyone\n How are you doing today ??' }: Props) {
export default function TextEditor({ placeholder, initialContent }: Props) {
const linkExtension = useMemo(() => {
const extension = new LinkExtension({ autoLink: true });
extension.addHandler('onClick', (_, data) => {
alert(`You clicked link: ${JSON.stringify(data)}`);
return true;
});
return extension;
}, []);
const extensions = useCallback(
() => [
new PlaceholderExtension({ placeholder }),
new LinkExtension({ autoLink: true }),
linkExtension,
new BoldExtension(),
// new StrikeExtension(),
new UnderlineExtension(),
@@ -48,8 +61,11 @@ export default function TextEditor({ placeholder, initialContent = 'Hello everyo
new OrderedListExtension(),
new ListItemExtension({ priority: ExtensionPriority.High, enableCollapsible: true }),
// new TaskListExtension(),
// new CodeExtension(),
// new CodeBlockExtension(),
new CodeExtension(),
new CodeBlockExtension({
supportedLanguages: [javascript, typescript]
}),
new ImageExtension({ enableResizing: true }),
// new TrailingNodeExtension(),
// new TableExtension(),
new MarkdownExtension({ copyAsMarkdown: false }),
@@ -68,7 +84,7 @@ export default function TextEditor({ placeholder, initialContent = 'Hello everyo
stringHandler: 'markdown',
});
return (
<div className='remirror-theme'>
<div className={`remirror-theme ${styles.wrapper} bg-white shadow-md`}>
<Remirror manager={manager} initialContent={initialContent}>
<Toolbar />
<EditorComponent />

View File

@@ -1,5 +1,5 @@
import { useActive, useChainedCommands, useCommands } from '@remirror/react';
import { FiBold, FiItalic, FiType, FiUnderline, FiAlignCenter, FiAlignLeft, FiAlignRight } from 'react-icons/fi'
import { FiBold, FiItalic, FiType, FiUnderline, FiAlignCenter, FiAlignLeft, FiAlignRight, FiCode } from 'react-icons/fi'
import { FaListOl, FaListUl, FaUndo, FaRedo } from 'react-icons/fa'
import {
@@ -19,11 +19,19 @@ export default function ToolButton({ cmd: _cmd }: Props) {
const commands = useCommands();
const active = useActive();
const chain = useChainedCommands();
// const chain = useChainedCommands();
// commands.undo
// commands.toggleLik
// active.list
const runCommand = (cmd: string, attrs?: any) => {
if (commands[cmd]) {
commands[cmd](attrs);
commands.focus();
}
}
if (_cmd === 'heading') {
return <Menu menuButton={
<MenuButton>
@@ -31,9 +39,9 @@ export default function ToolButton({ cmd: _cmd }: Props) {
className={`
w-36 h-36 flex justify-center items-center
${active.heading({}) ?
'font-bold bg-gray-200 text-black'
'font-bold bg-gray-300 text-black'
:
'hover:bg-gray-100'
'hover:bg-gray-200'
}
${!commands.toggleHeading.enabled() && 'opacity-40 text-gray-600 pointer-events-none'}
@@ -45,10 +53,10 @@ export default function ToolButton({ cmd: _cmd }: Props) {
} transition>
{Array(6).fill(0).map((_, idx) => <MenuItem
className={`
py-8 px-16 hover:bg-gray-100
py-8 px-16 hover:bg-gray-200
${active.heading({ level: idx + 1 }) && 'font-bold bg-gray-200'}
`}
onClick={() => chain.toggleHeading({ level: idx + 1 }).focus().run()}
onClick={() => runCommand('toggleHeading', { level: idx + 1 })}
>
Heading{idx + 1}
</MenuItem>)}
@@ -64,14 +72,14 @@ export default function ToolButton({ cmd: _cmd }: Props) {
className={`
w-36 h-36 flex justify-center items-center
${(activeCmd && active[activeCmd]()) ?
'font-bold bg-gray-200 text-black'
'font-bold bg-gray-300 text-black'
:
'hover:bg-gray-100'
'hover:bg-gray-200'
}
${!commands[cmd].enabled() && 'opacity-40 text-gray-600 pointer-events-none'}
`}
onClick={() => chain[cmd]().focus().run()}
onClick={() => runCommand(cmd)}
>
<Icon />
</button>
@@ -142,6 +150,11 @@ const cmdToBtn = {
activeCmd: null,
Icon: FaRedo,
},
code: {
cmd: 'toggleCodeBlock',
activeCmd: 'codeBlock',
Icon: FiCode,
},
} as const

View File

@@ -11,12 +11,13 @@ export default function Toolbar() {
return (
<div className='flex gap-24'>
<div className='flex gap-24 bg-gray-100'>
<div className="flex">
<ToolButton cmd='heading' />
<ToolButton cmd='bold' />
<ToolButton cmd='italic' />
<ToolButton cmd='underline' />
<ToolButton cmd='heading' />
<ToolButton cmd='code' />
</div>
<div className="flex">
<ToolButton cmd='leftAlign' />
@@ -26,6 +27,7 @@ export default function Toolbar() {
<ToolButton cmd='orderedList' />
</div>
<div className="flex ml-auto">
<ToolButton cmd='undo' />
<ToolButton cmd='redo' />

View File

@@ -0,0 +1,12 @@
.wrapper {
:global{
.ProseMirror,
.ProseMirror:active,
.ProseMirror:focus{
overflow: hidden;
box-shadow: none;
}
}
}