@ihsanabuhanifah/react-math-editor 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -99
- package/dist/components/SmartContentEditor.d.ts +27 -0
- package/dist/index.cjs +98 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10237 -9207
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,71 +1,79 @@
|
|
|
1
1
|
# @ihsanabuhanifah/react-math-editor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@ihsanabuhanifah/react-math-editor)
|
|
4
|
+
[](https://www.npmjs.com/package/@ihsanabuhanifah/react-math-editor)
|
|
5
|
+
[](https://github.com/ihsanabuhanifah)
|
|
6
|
+
[](https://react.dev)
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
A modern, lightweight Rich Text Editor and Math Viewer component for React. Powered by **Tiptap**, **KaTeX**, and **highlight.js**.
|
|
9
|
+
|
|
10
|
+
Designed specifically for educational platforms, exam builders (CBT), question banks, technical documentation, and math blogging.
|
|
7
11
|
|
|
8
12
|
---
|
|
9
13
|
|
|
10
|
-
## ✨
|
|
14
|
+
## ✨ Features
|
|
11
15
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
16
|
+
- 🧠 **SmartContentEditor Included:** Advanced editor supporting resizable & alignable images (25%, 50%, 75%, 100%), document attachments, YouTube video embeds, and AI paste modal.
|
|
17
|
+
- 📐 **Interactive LaTeX Math Formulas:** Popup dialog with live KaTeX preview. Click any formula chip inside the editor to edit it seamlessly.
|
|
18
|
+
- 📘 **Built-in Formula Cheat Sheet:** Comprehensive LaTeX dictionary covering Algebra, Trigonometry, Calculus, Matrices, and Logic.
|
|
19
|
+
- 📊 **Rich Table Support:** Insert tables (3x3), visually add/remove rows and columns, delete tables.
|
|
20
|
+
- 📋 **Auto-convert Markdown Tables:** Copy-paste markdown tables from AI assistants (ChatGPT, Claude, DeepSeek) and they automatically convert into interactive HTML tables.
|
|
21
|
+
- 🤖 **Smart AI Paste:** Dedicated modal & paste listener that formats markdown from AI into clean visual Tiptap nodes.
|
|
22
|
+
- 🎥 **YouTube & Attachment Embeds:** Embed responsive 16:9 YouTube videos and downloadable document attachments.
|
|
23
|
+
- 💻 **Syntax Highlighted Code Blocks:** Pre-configured code blocks with syntax highlighting using `highlight.js`.
|
|
24
|
+
- 🖼️ **Vendor-Agnostic Uploads:** Async callback props (`onUploadImage`, `onUploadFile`) connect to any storage backend.
|
|
25
|
+
- 🎨 **Self-Contained Styling:** Bundled standalone CSS (`style.css`), no TailwindCSS setup required on the consumer application.
|
|
26
|
+
- 👁️ **RenderMathHTML Viewer:** Companion lightweight component to safely render and display saved HTML content.
|
|
20
27
|
|
|
21
28
|
---
|
|
22
29
|
|
|
23
|
-
## 📦
|
|
24
|
-
|
|
25
|
-
Install paket ini melalui package manager favorit Anda:
|
|
30
|
+
## 📦 Installation
|
|
26
31
|
|
|
27
32
|
```bash
|
|
28
33
|
npm install @ihsanabuhanifah/react-math-editor
|
|
29
|
-
|
|
34
|
+
```
|
|
35
|
+
```bash
|
|
30
36
|
yarn add @ihsanabuhanifah/react-math-editor
|
|
31
|
-
|
|
37
|
+
```
|
|
38
|
+
```bash
|
|
32
39
|
pnpm add @ihsanabuhanifah/react-math-editor
|
|
33
40
|
```
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
> **Peer Dependencies:** Ensure `react` and `react-dom` (>= 18.0.0) are installed in your project.
|
|
36
43
|
|
|
37
44
|
---
|
|
38
45
|
|
|
39
|
-
## 🚀
|
|
46
|
+
## 🚀 Quick Start
|
|
40
47
|
|
|
41
|
-
### 1.
|
|
48
|
+
### 1. The Editor (`TextEditor`)
|
|
42
49
|
|
|
43
50
|
```tsx
|
|
44
51
|
import React, { useState } from "react";
|
|
45
52
|
import { TextEditor } from "@ihsanabuhanifah/react-math-editor";
|
|
46
|
-
import "@ihsanabuhanifah/react-math-editor/dist/style.css"; //
|
|
53
|
+
import "@ihsanabuhanifah/react-math-editor/dist/style.css"; // Import CSS once
|
|
47
54
|
|
|
48
|
-
export function
|
|
49
|
-
const [content, setContent] = useState("<p>
|
|
55
|
+
export function QuestionForm() {
|
|
56
|
+
const [content, setContent] = useState("<p>Solve for $x$: $x^2 - 5x + 6 = 0$</p>");
|
|
50
57
|
|
|
51
58
|
return (
|
|
52
|
-
<div style={{ maxWidth: 800, margin: "
|
|
59
|
+
<div style={{ maxWidth: 800, margin: "20px auto" }}>
|
|
60
|
+
<h2>Create Question</h2>
|
|
53
61
|
<TextEditor
|
|
54
62
|
value={content}
|
|
55
63
|
onChange={(html) => setContent(html)}
|
|
56
|
-
placeholder="
|
|
57
|
-
minHeight={
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
placeholder="Type questions, insert LaTeX math formulas, or paste tables..."
|
|
65
|
+
minHeight={220}
|
|
66
|
+
onUploadImage={async (file: File) => {
|
|
67
|
+
// Upload to your backend server / S3
|
|
60
68
|
const formData = new FormData();
|
|
61
|
-
formData.append("
|
|
69
|
+
formData.append("file", file);
|
|
62
70
|
|
|
63
|
-
const
|
|
71
|
+
const response = await fetch("/api/upload", {
|
|
64
72
|
method: "POST",
|
|
65
73
|
body: formData,
|
|
66
74
|
});
|
|
67
|
-
const
|
|
68
|
-
return
|
|
75
|
+
const result = await response.json();
|
|
76
|
+
return result.url; // Must return the image URL string
|
|
69
77
|
}}
|
|
70
78
|
/>
|
|
71
79
|
</div>
|
|
@@ -75,19 +83,19 @@ export function FormInputSoal() {
|
|
|
75
83
|
|
|
76
84
|
---
|
|
77
85
|
|
|
78
|
-
### 2.
|
|
86
|
+
### 2. The Content Viewer (`RenderMathHTML`)
|
|
79
87
|
|
|
80
|
-
|
|
88
|
+
Use `RenderMathHTML` wherever you need to display the formatted content to students or readers (e.g., exam page, preview card, blog post):
|
|
81
89
|
|
|
82
90
|
```tsx
|
|
83
91
|
import React from "react";
|
|
84
92
|
import { RenderMathHTML } from "@ihsanabuhanifah/react-math-editor";
|
|
85
93
|
import "@ihsanabuhanifah/react-math-editor/dist/style.css";
|
|
86
94
|
|
|
87
|
-
export function
|
|
95
|
+
export function QuestionCard({ htmlContent }: { htmlContent: string }) {
|
|
88
96
|
return (
|
|
89
|
-
<div className="card
|
|
90
|
-
<RenderMathHTML html={
|
|
97
|
+
<div className="card">
|
|
98
|
+
<RenderMathHTML html={htmlContent} />
|
|
91
99
|
</div>
|
|
92
100
|
);
|
|
93
101
|
}
|
|
@@ -95,82 +103,49 @@ export function DetailSoal({ soalHtml }: { soalHtml: string }) {
|
|
|
95
103
|
|
|
96
104
|
---
|
|
97
105
|
|
|
98
|
-
##
|
|
106
|
+
## ⚙️ API & Props Reference
|
|
99
107
|
|
|
100
108
|
### `<TextEditor />`
|
|
101
109
|
|
|
102
|
-
| Prop |
|
|
110
|
+
| Prop | Type | Default | Description |
|
|
103
111
|
| :--- | :--- | :--- | :--- |
|
|
104
|
-
| `value` | `string` | `""` |
|
|
105
|
-
| `onChange` | `(html: string) => void` | `undefined` | Callback
|
|
106
|
-
| `placeholder` | `string` | `"Tulis konten..."` |
|
|
107
|
-
| `disabled` | `boolean` | `false` |
|
|
108
|
-
| `readOnly` | `boolean` | `false` |
|
|
109
|
-
| `minHeight` | `number \| string` | `140` |
|
|
110
|
-
| `maxHeight` | `number \| string` | `600` |
|
|
111
|
-
| `onUploadImage` | `(file: File) => Promise<string>` | `undefined` |
|
|
112
|
-
| `toolbarExtra` | `React.ReactNode` | `undefined` | Slot
|
|
113
|
-
| `className` | `string` | `""` |
|
|
112
|
+
| `value` | `string` | `""` | Initial HTML string content |
|
|
113
|
+
| `onChange` | `(html: string) => void` | `undefined` | Callback fired on content change with updated HTML |
|
|
114
|
+
| `placeholder` | `string` | `"Tulis konten..."` | Placeholder text when editor is empty |
|
|
115
|
+
| `disabled` | `boolean` | `false` | Disables user interaction |
|
|
116
|
+
| `readOnly` | `boolean` | `false` | Read-only mode without toolbar |
|
|
117
|
+
| `minHeight` | `number \| string` | `140` | Minimum height for editing area (px or CSS string) |
|
|
118
|
+
| `maxHeight` | `number \| string` | `600` | Maximum height before scrolling |
|
|
119
|
+
| `onUploadImage` | `(file: File) => Promise<string>` | `undefined` | Async handler to upload images; returns the URL |
|
|
120
|
+
| `toolbarExtra` | `React.ReactNode` | `undefined` | Slot for custom action buttons in the toolbar |
|
|
121
|
+
| `className` | `string` | `""` | Additional CSS class names for outer container |
|
|
114
122
|
|
|
115
123
|
### `<RenderMathHTML />`
|
|
116
124
|
|
|
117
|
-
| Prop |
|
|
125
|
+
| Prop | Type | Default | Description |
|
|
118
126
|
| :--- | :--- | :--- | :--- |
|
|
119
|
-
| `html` | `string` | `""` |
|
|
120
|
-
| `className` | `string` | `""` |
|
|
121
|
-
| `style` | `React.CSSProperties` | `undefined` |
|
|
122
|
-
| `resolveImageUrl` | `(url: string) => Promise<string> \| string` | `undefined` |
|
|
127
|
+
| `html` | `string` | `""` | HTML string containing text, math, or tables to render |
|
|
128
|
+
| `className` | `string` | `""` | Additional CSS class for viewer container |
|
|
129
|
+
| `style` | `React.CSSProperties` | `undefined` | Inline styling for viewer container |
|
|
130
|
+
| `resolveImageUrl` | `(url: string) => Promise<string> \| string` | `undefined` | Optional resolver for private / signed image URLs |
|
|
123
131
|
|
|
124
132
|
---
|
|
125
133
|
|
|
126
|
-
##
|
|
127
|
-
|
|
128
|
-
### A. Publish ke NPM Registry
|
|
129
|
-
1. Masuk ke folder library:
|
|
130
|
-
```bash
|
|
131
|
-
cd packages/react-math-editor
|
|
132
|
-
```
|
|
133
|
-
2. Build bundle produksi:
|
|
134
|
-
```bash
|
|
135
|
-
npm run build
|
|
136
|
-
```
|
|
137
|
-
3. Login ke akun NPM Anda (jika belum):
|
|
138
|
-
```bash
|
|
139
|
-
npm login
|
|
140
|
-
```
|
|
141
|
-
4. Publikasikan paket:
|
|
142
|
-
```bash
|
|
143
|
-
npm publish --access public
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### B. Simpan di GitHub Repository
|
|
147
|
-
Anda bisa membuat repository baru di GitHub (misal `https://github.com/username/react-math-editor`):
|
|
148
|
-
```bash
|
|
149
|
-
cd packages/react-math-editor
|
|
150
|
-
git init
|
|
151
|
-
git add .
|
|
152
|
-
git commit -m "feat: initial release of react-math-editor"
|
|
153
|
-
git branch -M main
|
|
154
|
-
git remote add origin https://github.com/username/react-math-editor.git
|
|
155
|
-
git push -u origin main
|
|
156
|
-
```
|
|
134
|
+
## 💡 Framework Support
|
|
157
135
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
npm install git+https://github.com/username/react-math-editor.git
|
|
161
|
-
```
|
|
136
|
+
### Next.js (App Router / Pages Router)
|
|
137
|
+
Because KaTeX and Tiptap interact with the browser DOM, wrap `TextEditor` with `'use client'` or dynamic import if using Server Components:
|
|
162
138
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
```
|
|
168
|
-
Perintah ini akan menghasilkan file seperti `luvie-react-math-editor-1.0.0.tgz`. Di aplikasi lain, cukup jalankan:
|
|
169
|
-
```bash
|
|
170
|
-
npm install /path/ke/luvie-react-math-editor-1.0.0.tgz
|
|
139
|
+
```tsx
|
|
140
|
+
'use client';
|
|
141
|
+
import { TextEditor } from "@ihsanabuhanifah/react-math-editor";
|
|
142
|
+
import "@ihsanabuhanifah/react-math-editor/dist/style.css";
|
|
171
143
|
```
|
|
172
144
|
|
|
145
|
+
### Vite / Create React App / Remix
|
|
146
|
+
Works directly out of the box. Simply import the component and the stylesheet.
|
|
147
|
+
|
|
173
148
|
---
|
|
174
149
|
|
|
175
|
-
## 📄
|
|
176
|
-
|
|
150
|
+
## 📄 License
|
|
151
|
+
MIT © [Ihsan Abu Hanifah](https://github.com/ihsanabuhanifah)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export declare let lastActiveSmartEditor: any;
|
|
4
|
+
export declare function setLastActiveSmartEditor(ed: any): void;
|
|
5
|
+
export declare function getLastActiveSmartEditor(): any;
|
|
6
|
+
export declare function parseYouTubeEmbedUrl(url: string): string | null;
|
|
7
|
+
export declare function convertAiMarkdownToTipTapHtml(markdown: string): string;
|
|
8
|
+
export interface SmartContentEditorProps {
|
|
9
|
+
value: string;
|
|
10
|
+
handleChange?: (html: string) => void;
|
|
11
|
+
onChange?: (html: string) => void;
|
|
12
|
+
readOnly?: boolean;
|
|
13
|
+
minHeight?: number;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
onUploadImage?: (file: File) => Promise<string>;
|
|
16
|
+
onUploadFile?: (file: File) => Promise<{
|
|
17
|
+
url: string;
|
|
18
|
+
name: string;
|
|
19
|
+
size?: string | number;
|
|
20
|
+
}>;
|
|
21
|
+
showMathGraph?: boolean;
|
|
22
|
+
onPreview?: () => void;
|
|
23
|
+
error?: string;
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function SmartContentEditor({ value, handleChange, onChange, readOnly, minHeight, placeholder, onUploadImage, onUploadFile, showMathGraph, onPreview, error, className, }: SmartContentEditorProps): React.JSX.Element;
|
|
27
|
+
export default SmartContentEditor;
|