niimblr-content-editor
v0.0.10
Published
A Notion-style rich text editor built with [TipTap](https://tiptap.dev/), React, and full media support (images, video, audio, files, embeds, YouTube).
Readme
niimblr-content-editor
A Notion-style rich text editor built with TipTap, React, and full media support (images, video, audio, files, embeds, YouTube).
Features
- Rich editing – Headings, lists, blockquotes, code blocks, tables, math, mentions, emoji, text alignment, and more
- Media – Image, video, audio, and file nodes with upload hooks; optional deferred upload until “save”
- Embeds – YouTube and generic URL embeds
- UI – Floating toolbar, slash menu, drag handle, table of contents sidebar, theme toggle (light/dark)
Installation
npm install niimblr-content-editorPeer dependencies: React 18 or 19 and React DOM. Install them if not already present.
Usage
Import the CSS bundle once (for example in your app entry file) so all editor styles are available:
import "niimblr-content-editor/dist/index.css";import { useRef } from "react";
import {
NotionEditor,
type NotionEditorRef,
type TOnGetMediaURLFunction,
type TOnMediaUploadFunction,
} from "niimblr-content-editor";
const initialContent = "<p>Start writing...</p>";
function App() {
const editorRef = useRef<NotionEditorRef | null>(null);
const onMediaUpload: TOnMediaUploadFunction = async ({
file,
onProgress,
signal,
}) => {
// Upload file to your backend; call onProgress({ progress }); return { fileId }
const fileId = await yourUploadApi(file, onProgress, signal);
return { fileId };
};
const onGetMediaURL: TOnGetMediaURLFunction = ({ fileId }) => {
return fileId ? yourUrlForFileId(fileId) : null;
};
return (
<NotionEditor
content={initialContent}
onMediaUpload={onMediaUpload}
onGetMediaURL={onGetMediaURL}
onMediaDownload={async (info) => yourDownloadUrl(info)}
editorRef={editorRef}
isEditable={true}
deferUploadToSave={false}
headerChildren={
<button
type="button"
onClick={() => editorRef.current?.uploadMediaNodes()}
>
Save
</button>
}
/>
);
}Use editorRef.current?.getHTML() (or other TipTap APIs) when the user saves to read or persist content.
Main export: NotionEditor
| Prop | Type | Description |
| --------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| content | Content | Initial content for the editor (TipTap Content: HTML string or JSON). |
| immediatelyRender | boolean | Optional. When true (default), the editor DOM is rendered immediately; when false, rendering is deferred (e.g. for SSR/hydration). |
| onMediaUpload | TOnMediaUploadFunction | Required. Uploads a file; returns { fileId }. |
| onGetMediaURL | TOnGetMediaURLFunction | Required. Resolves fileId (and related info) to a display URL. |
| onMediaDownload | TOnMediaDownloadFunction | Required. Returns a URL for downloading a media node. |
| editorRef | RefObject<NotionEditorRef \| null> | Optional. Ref to the editor instance (via useImperativeHandle). Exposes TipTap APIs (e.g. getHTML()) and uploadMediaNodes() which runs deferred uploads and removals. Use with a custom Save button. |
| onMediaNodesRemoved | (items: Map<string, TMediaNodeRemovedInfo>) => void \| Promise<void> | Optional. Called when media nodes are removed (e.g. on uploadMediaNodes()), so the app can delete files. |
| isEditable | boolean | Optional. Whether the editor is editable. Defaults to true. |
| deferUploadToSave | boolean | Optional. If true, media is inserted with a preview and uploaded when editorRef.current?.uploadMediaNodes() runs. |
| themeMode | "light" \| "dark" | Optional. Default theme. Defaults to "dark". |
| placeholder | string | Optional. Placeholder text. Defaults to "Start writing...". |
| hideHeader | boolean | Optional. Hides the editor header/toolbar. |
| headerChildren | React.ReactNode | Optional. Renders inside the header (e.g. a custom Save button). |
| mediaConfig | Partial<Record<TMediaType, Partial<TMediaTypeConfig>>> | Optional. Per–media-type config (e.g. accept, maxSize, limit, and optional render for custom image/video components). |
Exported types
NotionEditorRef– Editor ref type; extends TipTapEditorwithuploadMediaNodes(): Promise<void>.TOnMediaUploadFunction,TOnGetMediaURLFunction,TOnMediaDownloadFunction,TOnMediaNodesRemovedFunctionTMediaUploadResult,TMediaNodeRemovedInfoTMediaType,TMediaTypeConfig(formediaConfig)TRenderImageComponentProps,TRenderVideoComponentProps(formediaConfig.image.render/mediaConfig.video.render)IImageAttrs,IMediaNodeAttrs,IVideoAttrsNotionEditorProps
License
Private / see repository.
