Skip to content

Commit

Permalink
refactor(#625): replace markdown editor
Browse files Browse the repository at this point in the history
  • Loading branch information
tonai committed Jan 27, 2025
1 parent 3aa315d commit 569f618
Show file tree
Hide file tree
Showing 8 changed files with 1,754 additions and 1,388 deletions.
52 changes: 29 additions & 23 deletions assets/components/Input/MarkdownEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { fr } from "@codegouvfr/react-dsfr";
import { useIsDark } from "@codegouvfr/react-dsfr/useIsDark";
import MDEditor from "@uiw/react-md-editor";
import { CSSProperties, FC } from "react";
import { FC } from "react";
import { MarkdownEditor as TiptapEditor } from "react-dsfr-tiptap/markdown";
import { ControlImage, ControlLink, ControlUnlink } from "react-dsfr-tiptap/dialog";
import StarterKit from "@tiptap/starter-kit";
import Image from "@tiptap/extension-image";
import Link from "@tiptap/extension-link";
import Placeholder from "@tiptap/extension-placeholder";
import { Markdown } from "tiptap-markdown";

import getLocaleCommands from "../../modules/react-md/react-md-commands";
import "../../sass/components/tiptap.scss";

type MarkdownEditorProps = {
label?: string;
Expand All @@ -16,17 +22,9 @@ type MarkdownEditorProps = {
};

const MarkdownEditor: FC<MarkdownEditorProps> = (props) => {
const { label, hintText, value, state, stateRelatedMessage, placeholder, onChange } = props;
const { label, hintText, value, state, stateRelatedMessage, placeholder = "", onChange } = props;
const { isDark } = useIsDark();

const customStyle: CSSProperties = {
backgroundColor: fr.colors.decisions.background.contrast.grey.default,
borderRadius: `${fr.spacing("1v")} ${fr.spacing("1v")} 0 0`,
boxShadow: `inset 0 -2px 0 0 var(${fr.colors.decisions.border.plain.grey.default})`,
marginTop: fr.spacing("1v"),
fontFamily: "Marianne, arial, sans-serif",
};

return (
<div className={fr.cx("fr-input-group", state === "error" && "fr-input-group--error")} data-color-mode={isDark ? "dark" : "light"}>
{label && (
Expand All @@ -35,17 +33,25 @@ const MarkdownEditor: FC<MarkdownEditorProps> = (props) => {
{hintText && <span className="fr-hint-text">{hintText}</span>}
</label>
)}
<MDEditor
value={value}
height={200}
commands={getLocaleCommands("fr")}
extraCommands={[]}
textareaProps={{
placeholder: placeholder,
}}
onChange={(newValue = "") => onChange(newValue)}
style={customStyle}
previewOptions={{ style: customStyle }}
<TiptapEditor
content={value}
controls={[
["Bold", "Italic", "Strike", "Code", "ClearFormatting"],
["H1", "H2", "H3", "H4", "H5", "H6", "Paragraph"],
["BulletList", "OrderedList", "CodeBlock", "Blockquote", "HorizontalRule"],
[ControlLink, ControlUnlink, ControlImage],
["Undo", "Redo"],
]}
extensions={[
StarterKit,
Image,
Link,
Placeholder.configure({
placeholder,
}),
Markdown,
]}
onContentUpdate={onChange}
/>
{state === "error" && stateRelatedMessage !== undefined && <p className={fr.cx("fr-error-text")}>{stateRelatedMessage}</p>}
</div>
Expand Down
30 changes: 30 additions & 0 deletions assets/components/Utils/MarkdownRenderer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { FC, HTMLAttributes } from "react";
import { symToStr } from "tsafe/symToStr";
import markdownit from "markdown-it";

import "../../sass/components/tiptap.scss";

const md = markdownit({
breaks: true,
html: false,
linkify: true,
quotes: ["«\xA0", "\xA0»", "‹\xA0", "\xA0›"],
typographer: true,
});

interface MarkdownRendererProps extends HTMLAttributes<HTMLDivElement> {
content: string;
}

const MarkdownRenderer: FC<MarkdownRendererProps> = (props) => {
const { className, content, ...rest } = props;
const result = md.render(content);
const classNames = ["fr-tiptap"];
if (className) {
classNames.push(className);
}
return <div {...rest} className={classNames.join(" ")} dangerouslySetInnerHTML={{ __html: result }} />;
};
MarkdownRenderer.displayName = symToStr({ MarkdownRenderer });

export default MarkdownRenderer;
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { fr } from "@codegouvfr/react-dsfr";
import MDEditor from "@uiw/react-md-editor";
import { CSSProperties, FC, ReactNode } from "react";
import "react-dsfr-tiptap/index.css";

import MarkdownRenderer from "../../../../../components/Utils/MarkdownRenderer";

type MetadataFieldProps = {
title?: ReactNode;
Expand Down Expand Up @@ -32,14 +34,7 @@ const MetadataField: FC<MetadataFieldProps> = ({ title, content, hintText, markd
)}

{markdown && typeof content === "string" ? (
<MDEditor.Markdown
className={fr.cx()}
source={content}
style={customStyle}
components={{
a: (props) => <a target="_blank" rel="noreferrer" {...props} />,
}}
/>
<MarkdownRenderer content={content} style={customStyle} />
) : typeof content === "string" ? (
<p className={fr.cx("fr-m-0")}>{content}</p>
) : (
Expand Down
85 changes: 0 additions & 85 deletions assets/modules/react-md/react-md-commands.ts

This file was deleted.

64 changes: 0 additions & 64 deletions assets/modules/react-md/react-md-locales.ts

This file was deleted.

11 changes: 11 additions & 0 deletions assets/sass/components/tiptap.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.fr-tiptap > :last-child {
margin-bottom: 0 !important;
}

.tiptap p.is-editor-empty:first-child::before {
color: #adb5bd;
content: attr(data-placeholder);
float: left;
height: 0;
pointer-events: none;
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": "^7.4||^8.2",
"php": "^7.4||^8.2||^8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"cweagans/composer-patches": "^1.7",
Expand Down
Loading

0 comments on commit 569f618

Please sign in to comment.