mirror of
https://github.com/muerwre/markdown-home-tab.git
synced 2025-04-25 08:56:41 +07:00
made simplier editor, added color coding
This commit is contained in:
parent
601eda17de
commit
c1533e9cb9
15 changed files with 287 additions and 43 deletions
41
src/modules/editor/components/ReactMarkdownEditor/index.tsx
Normal file
41
src/modules/editor/components/ReactMarkdownEditor/index.tsx
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { ChangeEvent, FC, useCallback, useMemo } from "react";
|
||||
import styles from "./styles.module.scss";
|
||||
import { useTheme } from "~/modules/theme/context/ThemeContext";
|
||||
|
||||
interface ReactMarkdownEditorProps {
|
||||
value: string;
|
||||
onChange: (val: string) => void;
|
||||
}
|
||||
|
||||
const ReactMarkdownEditor: FC<ReactMarkdownEditorProps> = ({
|
||||
value,
|
||||
onChange,
|
||||
}) => {
|
||||
const changeHandler = useCallback(
|
||||
(event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
onChange(event.target.value);
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const { paddingHorizontal, paddingVertical } = useTheme();
|
||||
|
||||
const style = useMemo(
|
||||
() => ({
|
||||
padding: `${paddingVertical}px ${paddingHorizontal}px`,
|
||||
}),
|
||||
[paddingHorizontal, paddingVertical]
|
||||
);
|
||||
|
||||
return (
|
||||
<textarea
|
||||
onChange={changeHandler}
|
||||
className={styles.textarea}
|
||||
style={style}
|
||||
>
|
||||
{value}
|
||||
</textarea>
|
||||
);
|
||||
};
|
||||
|
||||
export { ReactMarkdownEditor };
|
|
@ -0,0 +1,9 @@
|
|||
.textarea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
}
|
20
src/modules/editor/components/ReactMarkdownViewer/index.tsx
Normal file
20
src/modules/editor/components/ReactMarkdownViewer/index.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { FC } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { useContainerPaddings } from "~/modules/theme/hooks/useContainerPaddings";
|
||||
import styles from "./styles.module.scss";
|
||||
|
||||
interface ReactMarkdownViewerProps {
|
||||
value: string;
|
||||
}
|
||||
|
||||
const ReactMarkdownViewer: FC<ReactMarkdownViewerProps> = ({ value }) => {
|
||||
const style = useContainerPaddings();
|
||||
|
||||
return (
|
||||
<div style={style} className={styles.editor}>
|
||||
<ReactMarkdown>{value}</ReactMarkdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { ReactMarkdownViewer };
|
|
@ -0,0 +1,11 @@
|
|||
.editor {
|
||||
& > :first-child {
|
||||
margin-top: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
& > :last-child {
|
||||
margin-bottom: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ import {
|
|||
GapCursorExtension,
|
||||
} from "remirror/extensions";
|
||||
import styles from "./styles.module.scss";
|
||||
import { useContainerPaddings } from "~/modules/theme/hooks/useContainerPaddings";
|
||||
|
||||
interface RemirrorEditorProps {
|
||||
locked: boolean;
|
||||
|
@ -63,23 +64,28 @@ const RemirrorEditor: FC<RemirrorEditorProps> = ({
|
|||
[onChange, setState]
|
||||
);
|
||||
|
||||
const style = useContainerPaddings();
|
||||
|
||||
return (
|
||||
<Remirror
|
||||
placeholder="Start typing..."
|
||||
manager={manager}
|
||||
classNames={[styles.editor]}
|
||||
editable={!locked}
|
||||
onChange={onStateChange}
|
||||
state={state}
|
||||
>
|
||||
<EditorComponent />
|
||||
{!locked && (
|
||||
<FloatingToolbar>
|
||||
<FormattingButtonGroup />
|
||||
<HeadingLevelButtonGroup />
|
||||
</FloatingToolbar>
|
||||
)}
|
||||
</Remirror>
|
||||
<div className={styles.wrapper} style={style}>
|
||||
<Remirror
|
||||
placeholder="Start typing..."
|
||||
manager={manager}
|
||||
classNames={[styles.editor]}
|
||||
editable={!locked}
|
||||
onChange={onStateChange}
|
||||
state={state}
|
||||
autoFocus
|
||||
>
|
||||
<EditorComponent />
|
||||
{!locked && (
|
||||
<FloatingToolbar>
|
||||
<FormattingButtonGroup />
|
||||
<HeadingLevelButtonGroup />
|
||||
</FloatingToolbar>
|
||||
)}
|
||||
</Remirror>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
.wrapper {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
& > :global(.remirror-editor-wrapper) {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.editor {
|
||||
outline: none;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
& > :first-child {
|
||||
margin-top: 0 !important;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { FC } from "react";
|
||||
import styles from "./styles.module.scss";
|
||||
import { ReactMarkdownEditor } from "../../components/ReactMarkdownEditor";
|
||||
import { ReactMarkdownViewer } from "../../components/ReactMarkdownViewer";
|
||||
import { usePersistedValue } from "./hooks/usePersistedValue";
|
||||
import { RemirrorEditor } from "../../components/RemirrorEditor";
|
||||
import styles from "./styles.module.scss";
|
||||
|
||||
interface MarkdownEditorContainerProps {
|
||||
id: string;
|
||||
|
@ -16,7 +17,19 @@ export const MarkdownEditorContainer: FC<MarkdownEditorContainerProps> = ({
|
|||
|
||||
return (
|
||||
<div className={styles.editor}>
|
||||
<RemirrorEditor value={value} onChange={setValue} locked={locked} />
|
||||
{/*
|
||||
locked ? (
|
||||
<ReactMarkdownViewer value={value} />
|
||||
) : (
|
||||
<ReactMarkdownEditor value={value} onChange={setValue} />
|
||||
)
|
||||
*/}
|
||||
{locked ? (
|
||||
<ReactMarkdownViewer value={value} />
|
||||
) : (
|
||||
<ReactMarkdownEditor value={value} onChange={setValue} />
|
||||
// <RemirrorEditor value={value} onChange={setValue} locked={locked} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
.editor {
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
overflow: scroll;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
|
|
@ -26,27 +26,27 @@ const GridLayoutItemWrapper: FC<GridLayoutItemWrapperProps> = ({
|
|||
}) => (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.menu}>
|
||||
<IconButton
|
||||
onClick={splitVertical}
|
||||
role="button"
|
||||
className={styles.button}
|
||||
>
|
||||
<SplitVertical />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={splitHorizontal}
|
||||
role="button"
|
||||
className={styles.button}
|
||||
>
|
||||
<SplitHorizontal />
|
||||
</IconButton>
|
||||
|
||||
{!locked && (
|
||||
<>
|
||||
<IconButton
|
||||
onClick={splitVertical}
|
||||
role="button"
|
||||
className={styles.button}
|
||||
>
|
||||
<SplitVertical />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={splitHorizontal}
|
||||
role="button"
|
||||
className={styles.button}
|
||||
>
|
||||
<SplitHorizontal />
|
||||
</IconButton>
|
||||
<IconButton onClick={remove} role="button" className={styles.button}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</>
|
||||
<IconButton onClick={remove} role="button" className={styles.button}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
<IconButton onClick={lock} role="button" className={styles.button}>
|
||||
{locked ? <Locked /> : <Unlocked />}
|
||||
</IconButton>
|
||||
|
|
|
@ -5,6 +5,8 @@ import { FontFamily } from "../../constants/fonts";
|
|||
export const defaultTheme = {
|
||||
theme: Theme.Dark,
|
||||
font: FontFamily.Inter,
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 16,
|
||||
};
|
||||
|
||||
export const ThemeContext = createContext(defaultTheme);
|
||||
|
|
12
src/modules/theme/hooks/useContainerPaddings.ts
Normal file
12
src/modules/theme/hooks/useContainerPaddings.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { useMemo } from "react";
|
||||
import { useTheme } from "~/modules/theme/context/ThemeContext";
|
||||
export const useContainerPaddings = () => {
|
||||
const { paddingHorizontal, paddingVertical } = useTheme();
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
padding: `${paddingVertical}px ${paddingHorizontal}px`,
|
||||
}),
|
||||
[paddingHorizontal, paddingVertical]
|
||||
);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue