mirror of
https://github.com/aljazceru/landscape-template.git
synced 2025-12-17 06:14:27 +01:00
feat: added code,links, & styling the editor
This commit is contained in:
1924
package-lock.json
generated
1924
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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' />
|
||||
|
||||
12
src/Components/Inputs/TextEditor/styles.module.scss
Normal file
12
src/Components/Inputs/TextEditor/styles.module.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
.wrapper {
|
||||
|
||||
:global{
|
||||
.ProseMirror,
|
||||
.ProseMirror:active,
|
||||
.ProseMirror:focus{
|
||||
overflow: hidden;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user