From 175d27ad45cd7b6ec7d5ad8d7d75abe0b758a30d Mon Sep 17 00:00:00 2001 From: Tony CABAYE Date: Thu, 23 Jan 2025 11:07:47 +0100 Subject: [PATCH] test(#2): add placeholder example --- examples/package.json | 1 + examples/src/Custom.tsx | 20 +++++++++++++------ examples/src/custom.css | 7 +++++++ package-lock.json | 14 +++++++++++++ packages/react-dsfr-tiptap/README.md | 1 + .../src/components/Content.tsx | 11 +++++++--- .../src/components/Loader.tsx | 7 ++++--- 7 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 examples/src/custom.css diff --git a/examples/package.json b/examples/package.json index 539fae5..43365ba 100644 --- a/examples/package.json +++ b/examples/package.json @@ -20,6 +20,7 @@ "@tiptap/extension-highlight": "^2.10.4", "@tiptap/extension-image": "^2.10.4", "@tiptap/extension-link": "^2.10.4", + "@tiptap/extension-placeholder": "^2.11.3", "@tiptap/extension-subscript": "^2.10.4", "@tiptap/extension-superscript": "^2.10.4", "@tiptap/extension-text-align": "^2.10.4", diff --git a/examples/src/Custom.tsx b/examples/src/Custom.tsx index 6561ac6..c33ad16 100644 --- a/examples/src/Custom.tsx +++ b/examples/src/Custom.tsx @@ -3,19 +3,27 @@ import { RichTextEditor } from "react-dsfr-tiptap"; import { ControlImage, ControlLink, ControlUnlink, ControlYoutube } from "react-dsfr-tiptap/dialog"; import StarterKit from "@tiptap/starter-kit"; import Link from "@tiptap/extension-link"; +import Placeholder from "@tiptap/extension-placeholder"; import { CustomControl1, CustomControl2, CustomControl3 } from "./TiptapCustomButtons"; +import "./custom.css"; const Custom = () => { - const [content, setContent] = useState(` -

-this is a basic example of Tiptap. Sure, there are all kind of basic text styles you’d probably expect from a text editor? -

-`); + const [content, setContent] = useState(""); return ( <> - setContent(editor.getHTML())}> + setContent(editor.getHTML())} + > diff --git a/examples/src/custom.css b/examples/src/custom.css new file mode 100644 index 0000000..077d6c1 --- /dev/null +++ b/examples/src/custom.css @@ -0,0 +1,7 @@ +.tiptap p.is-editor-empty:first-child::before { + color: #adb5bd; + content: attr(data-placeholder); + float: left; + height: 0; + pointer-events: none; +} diff --git a/package-lock.json b/package-lock.json index 5ffd0d2..696bb34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "@tiptap/extension-highlight": "^2.10.4", "@tiptap/extension-image": "^2.10.4", "@tiptap/extension-link": "^2.10.4", + "@tiptap/extension-placeholder": "^2.11.3", "@tiptap/extension-subscript": "^2.10.4", "@tiptap/extension-superscript": "^2.10.4", "@tiptap/extension-text-align": "^2.10.4", @@ -4454,6 +4455,19 @@ "@tiptap/core": "^2.7.0" } }, + "node_modules/@tiptap/extension-placeholder": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.11.3.tgz", + "integrity": "sha512-wXNcqsxkc+85NPrNpA/iuLa86RL2oOiOGWheJoIjtW2m9BEJSDsyHdUa9Nxwm28+PgonzG1uUfEv4JEzT5m4xg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, "node_modules/@tiptap/extension-strike": { "version": "2.11.2", "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.11.2.tgz", diff --git a/packages/react-dsfr-tiptap/README.md b/packages/react-dsfr-tiptap/README.md index a76d983..a3dc255 100644 --- a/packages/react-dsfr-tiptap/README.md +++ b/packages/react-dsfr-tiptap/README.md @@ -292,6 +292,7 @@ Les 2 composants `RichTextEditor` et `MarkdownEditor` fonctionne de la même man | Props | Type | Valeur par défaut | Description | | ----------------- | ------------------------------------------------------------------------------------- | ------------------- | ----------------------------------------------------------------- | | `content` | `string` | `""` | Contenu de la zone de texte riche | +| `contentProps` | `IContentProps` | `{}` | Props pour le composant du contenu | | `controlMap` | `Partial ReactNode) \| LazyExoticComponent<() => ReactNode>>>` | `{}` | Permet de configurer les composants des boutons préconfigurés | | `controls` | `(Control \| (() => ReactNode) \| LazyExoticComponent<() => ReactNode>)[][]` | `defaultControls` | Permet de configurer les boutons du menu | | `extensionLoader` | `Partial Promise>>` | `{}` | Permet de charger dynamiquement des extensions | diff --git a/packages/react-dsfr-tiptap/src/components/Content.tsx b/packages/react-dsfr-tiptap/src/components/Content.tsx index e08a6c6..a73fe0a 100644 --- a/packages/react-dsfr-tiptap/src/components/Content.tsx +++ b/packages/react-dsfr-tiptap/src/components/Content.tsx @@ -1,14 +1,19 @@ import { fr } from "@codegouvfr/react-dsfr"; -import { EditorContent } from "@tiptap/react"; +import { EditorContent, EditorContentProps } from "@tiptap/react"; import { tss } from "tss-react"; import { useEditor } from "../contexts/editor"; +import { ForwardedRef } from "react"; -function Content() { +export interface IContentProps extends Omit { + ref?: ForwardedRef; +} + +function Content(props: IContentProps) { const editor = useEditor(); const { classes } = useStyles(); - return ; + return ; } const useStyles = tss.withName(Content.name).create(() => ({ diff --git a/packages/react-dsfr-tiptap/src/components/Loader.tsx b/packages/react-dsfr-tiptap/src/components/Loader.tsx index 1ea14a2..5cb3034 100644 --- a/packages/react-dsfr-tiptap/src/components/Loader.tsx +++ b/packages/react-dsfr-tiptap/src/components/Loader.tsx @@ -5,7 +5,7 @@ import StarterKit from "@tiptap/starter-kit"; import { Control } from "../types/controls"; import { ControlComponent, richTextEditorControls } from "../utils/controls"; -import RichTextEditorContent from "./Content"; +import RichTextEditorContent, { IContentProps } from "./Content"; import RichTextEditorMenu from "./Menu"; import RichTextEditorProvider, { IProviderProps } from "./Provider"; import RichTextEditorGroup from "./Group"; @@ -24,6 +24,7 @@ export type Extension = | "youtube"; export interface ILoaderProps extends Omit { + contentProps?: IContentProps; controlMap?: Partial>; controls: (Control | ControlComponent)[][]; extensionLoader?: Partial Promise>>; @@ -80,7 +81,7 @@ const extensionDefaultConfiguration = { }; function Loader(props: ILoaderProps) { - const { controlMap = {}, controls, extensionLoader = {}, menu = "top", ...rest } = props; + const { contentProps = {}, controlMap = {}, controls, extensionLoader = {}, menu = "top", ...rest } = props; const [extensions, setExtensions] = useState>>(() => Object.fromEntries(props.extensions?.map((extension) => [extension.name, extension]) ?? [["starterKit", StarterKit]]) ); @@ -152,7 +153,7 @@ function Loader(props: ILoaderProps) { {components} ))} - {menu === "top" && } + {menu === "top" && } ); }