@malaya_jeeva/rich-text-editor 1.0.6 → 1.0.7
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 +50 -17
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +26 -34
- package/dist/index.mjs +26 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,15 +49,48 @@ export default function Page() {
|
|
|
49
49
|
| ---------- | ------------------------- | -------- | ---------------------------------------- |
|
|
50
50
|
| `value` | `string` | No | Initial HTML content (read on first mount only) |
|
|
51
51
|
| `onChange` | `(value: string) => void` | No | Fires with full `innerHTML` on every change |
|
|
52
|
+
| `toolbar` | `ToolbarItem[]` | No | Controls which toolbar buttons are shown. If omitted, all buttons are shown |
|
|
52
53
|
|
|
53
54
|
### Type export
|
|
54
55
|
|
|
55
56
|
```ts
|
|
56
|
-
import type { RichTextEditorProps } from '@malaya_jeeva/rich-text-editor'
|
|
57
|
+
import type { RichTextEditorProps, ToolbarItem } from '@malaya_jeeva/rich-text-editor'
|
|
57
58
|
```
|
|
58
59
|
|
|
59
60
|
---
|
|
60
61
|
|
|
62
|
+
## 🛠️ Toolbar Customization
|
|
63
|
+
|
|
64
|
+
Pass a `toolbar` array to control exactly which buttons appear. If the prop is omitted, **all buttons are shown** — fully backward compatible.
|
|
65
|
+
|
|
66
|
+
### All available `ToolbarItem` keys
|
|
67
|
+
|
|
68
|
+
| Key | Button | Description |
|
|
69
|
+
| --- | ------ | ----------- |
|
|
70
|
+
| `bold` | **B** | Bold text |
|
|
71
|
+
| `italic` | *I* | Italic text |
|
|
72
|
+
| `underline` | <u>U</u> | Underline text |
|
|
73
|
+
| `color` | A̲ | Text color picker (palette + HSV wheel + remove) |
|
|
74
|
+
| `blockFormat` | Paragraph ▾ | Block format dropdown (Paragraph, H1, H2, H3) |
|
|
75
|
+
| `alignLeft` | ≡ | Align text left |
|
|
76
|
+
| `alignCenter` | ≡ | Align text center |
|
|
77
|
+
| `alignRight` | ≡ | Align text right |
|
|
78
|
+
| `alignJustify` | ≡ | Justify text |
|
|
79
|
+
| `bulletList` | • | Unordered / bullet list |
|
|
80
|
+
| `numberedList` | 1. | Ordered / numbered list |
|
|
81
|
+
| `indent` | → | Increase indent (or go deeper in list) |
|
|
82
|
+
| `outdent` | ← | Decrease indent (or go back up in list) |
|
|
83
|
+
| `link` | 🔗 | Insert / edit hyperlink |
|
|
84
|
+
| `codeBlock` | `</>` | Wrap selection in `<pre><code>` |
|
|
85
|
+
| `image` | 🖼 | Insert image (upload, URL, or drop) |
|
|
86
|
+
| `table` | ⊞ | Insert table (grid picker up to 8×8) |
|
|
87
|
+
| `html` | HTML | Toggle between Visual and HTML source view |
|
|
88
|
+
| `copyHtml` | ⎘ | Copy current HTML to clipboard |
|
|
89
|
+
|
|
90
|
+
> **Note:** Separators between groups are rendered automatically — they appear only when buttons exist on both sides, so you never get a leading, trailing, or double separator regardless of your selection.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
61
94
|
## ✨ Features
|
|
62
95
|
|
|
63
96
|
### Text Formatting
|
|
@@ -112,15 +145,15 @@ import type { RichTextEditorProps } from '@malaya_jeeva/rich-text-editor'
|
|
|
112
145
|
|
|
113
146
|
## 🧠 Keyboard Shortcuts
|
|
114
147
|
|
|
115
|
-
| Shortcut
|
|
116
|
-
|
|
|
117
|
-
| `Ctrl + B`
|
|
118
|
-
| `Ctrl + I`
|
|
119
|
-
| `Ctrl + U`
|
|
120
|
-
| `Tab`
|
|
121
|
-
| `Shift + Tab`
|
|
122
|
-
| `Enter` (link bar) | Apply link
|
|
123
|
-
| `Escape` (link bar) | Dismiss link bar
|
|
148
|
+
| Shortcut | Action |
|
|
149
|
+
| -------- | ------ |
|
|
150
|
+
| `Ctrl + B` | Bold |
|
|
151
|
+
| `Ctrl + I` | Italic |
|
|
152
|
+
| `Ctrl + U` | Underline |
|
|
153
|
+
| `Tab` | Indent list item / move to next table cell |
|
|
154
|
+
| `Shift + Tab` | Outdent list item / move to previous table cell |
|
|
155
|
+
| `Enter` (link bar) | Apply link |
|
|
156
|
+
| `Escape` (link bar) | Dismiss link bar |
|
|
124
157
|
|
|
125
158
|
---
|
|
126
159
|
|
|
@@ -129,13 +162,13 @@ import type { RichTextEditorProps } from '@malaya_jeeva/rich-text-editor'
|
|
|
129
162
|
Click any inserted image to open the image control panel.
|
|
130
163
|
|
|
131
164
|
### Style tab
|
|
132
|
-
| Control
|
|
133
|
-
|
|
|
134
|
-
| Display
|
|
135
|
-
| Alignment
|
|
136
|
-
| Width
|
|
137
|
-
| Alt text
|
|
138
|
-
| Delete
|
|
165
|
+
| Control | Options |
|
|
166
|
+
| ------- | ------- |
|
|
167
|
+
| Display | Block (full row) · Inline (flows with text) |
|
|
168
|
+
| Alignment | Left · Center · Right |
|
|
169
|
+
| Width | 25% · 50% · 75% · 100% · Original size · Custom (e.g. `300px`) |
|
|
170
|
+
| Alt text | Free text input |
|
|
171
|
+
| Delete | Removes the image from the editor |
|
|
139
172
|
|
|
140
173
|
### Caption tab
|
|
141
174
|
Wraps the image in `<figure>` + `<figcaption>`. The caption always renders below the image regardless of float alignment.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
+
type ToolbarItem = "bold" | "italic" | "underline" | "color" | "blockFormat" | "alignLeft" | "alignCenter" | "alignRight" | "alignJustify" | "bulletList" | "numberedList" | "indent" | "outdent" | "link" | "codeBlock" | "image" | "table" | "html" | "copyHtml";
|
|
3
4
|
type RichTextEditorProps = {
|
|
4
5
|
value?: string;
|
|
5
6
|
onChange?: (value: string) => void;
|
|
7
|
+
toolbar?: ToolbarItem[];
|
|
6
8
|
};
|
|
7
9
|
|
|
8
|
-
declare function RichTextEditor({ value, onChange }: RichTextEditorProps): ReactElement;
|
|
10
|
+
declare function RichTextEditor({ value, onChange, toolbar }: RichTextEditorProps): ReactElement;
|
|
9
11
|
|
|
10
12
|
export { type RichTextEditorProps, RichTextEditor as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
+
type ToolbarItem = "bold" | "italic" | "underline" | "color" | "blockFormat" | "alignLeft" | "alignCenter" | "alignRight" | "alignJustify" | "bulletList" | "numberedList" | "indent" | "outdent" | "link" | "codeBlock" | "image" | "table" | "html" | "copyHtml";
|
|
3
4
|
type RichTextEditorProps = {
|
|
4
5
|
value?: string;
|
|
5
6
|
onChange?: (value: string) => void;
|
|
7
|
+
toolbar?: ToolbarItem[];
|
|
6
8
|
};
|
|
7
9
|
|
|
8
|
-
declare function RichTextEditor({ value, onChange }: RichTextEditorProps): ReactElement;
|
|
10
|
+
declare function RichTextEditor({ value, onChange, toolbar }: RichTextEditorProps): ReactElement;
|
|
9
11
|
|
|
10
12
|
export { type RichTextEditorProps, RichTextEditor as default };
|
package/dist/index.js
CHANGED
|
@@ -1109,7 +1109,7 @@ function ImageEditor({ img, containerRef, onClose, onDelete, onChange }) {
|
|
|
1109
1109
|
|
|
1110
1110
|
// src/RichTextEditor.tsx
|
|
1111
1111
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1112
|
-
function RichTextEditor({ value, onChange }) {
|
|
1112
|
+
function RichTextEditor({ value, onChange, toolbar }) {
|
|
1113
1113
|
var _a;
|
|
1114
1114
|
const editorRef = (0, import_react5.useRef)(null);
|
|
1115
1115
|
const editorAreaRef = (0, import_react5.useRef)(null);
|
|
@@ -1461,15 +1461,16 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1461
1461
|
const canMerge = selCells.length >= 2;
|
|
1462
1462
|
const canSplit = fmt.cellMerged;
|
|
1463
1463
|
const backdrop = { position: "fixed", inset: 0, zIndex: 199 };
|
|
1464
|
+
const show = (key) => !toolbar || toolbar.includes(key);
|
|
1464
1465
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: "1rem 0" }, children: [
|
|
1465
1466
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: CSS }),
|
|
1466
1467
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
|
|
1467
1468
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rte-toolbar", children: [
|
|
1468
1469
|
!isCode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1469
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
|
|
1470
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("italic"), title: "Italic (Ctrl+I)", active: fmt.italic, style: { fontStyle: "italic", fontFamily: "Georgia,serif" }, children: "I" }),
|
|
1471
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("underline"), title: "Underline (Ctrl+U)", active: fmt.underline, style: { textDecoration: "underline" }, children: "U" }),
|
|
1472
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1470
|
+
show("bold") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
|
|
1471
|
+
show("italic") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("italic"), title: "Italic (Ctrl+I)", active: fmt.italic, style: { fontStyle: "italic", fontFamily: "Georgia,serif" }, children: "I" }),
|
|
1472
|
+
show("underline") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("underline"), title: "Underline (Ctrl+U)", active: fmt.underline, style: { textDecoration: "underline" }, children: "U" }),
|
|
1473
|
+
show("color") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1473
1474
|
showColor && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: backdrop, onMouseDown: () => setShowColor(false) }),
|
|
1474
1475
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1475
1476
|
Btn,
|
|
@@ -1501,8 +1502,8 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1501
1502
|
}
|
|
1502
1503
|
) })
|
|
1503
1504
|
] }),
|
|
1504
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1505
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1505
|
+
(show("bold") || show("italic") || show("underline") || show("color")) && (show("blockFormat") || show("alignLeft") || show("alignCenter") || show("alignRight") || show("alignJustify")) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1506
|
+
show("blockFormat") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1506
1507
|
"select",
|
|
1507
1508
|
{
|
|
1508
1509
|
className: "rte-select",
|
|
@@ -1525,20 +1526,20 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1525
1526
|
]
|
|
1526
1527
|
}
|
|
1527
1528
|
),
|
|
1528
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1529
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyLeft"), title: "Align left", active: fmt.aL, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "left" }) }),
|
|
1530
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyCenter"), title: "Align center", active: fmt.aC, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "center" }) }),
|
|
1531
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyRight"), title: "Align right", active: fmt.aR, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "right" }) }),
|
|
1532
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyFull"), title: "Justify", active: fmt.aJ, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "justify" }) }),
|
|
1533
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1534
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("insertUnorderedList"), title: "Bullet list", active: fmt.ul, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoUL, {}) }),
|
|
1535
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("insertOrderedList"), title: "Numbered list", active: fmt.ol, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoOL, {}) }),
|
|
1536
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("indent"), title: "Indent (Tab)", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoIndent, {}) }),
|
|
1537
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("outdent"), title: "Outdent (Shift+Tab)", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoOutdent, {}) }),
|
|
1538
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1539
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: openLinkBar, title: "Insert link", active: linkBar, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoLink, {}) }),
|
|
1540
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: insertCodeBlock, title: "Code block", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoCode, {}) }),
|
|
1541
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1529
|
+
show("blockFormat") && (show("alignLeft") || show("alignCenter") || show("alignRight") || show("alignJustify")) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1530
|
+
show("alignLeft") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyLeft"), title: "Align left", active: fmt.aL, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "left" }) }),
|
|
1531
|
+
show("alignCenter") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyCenter"), title: "Align center", active: fmt.aC, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "center" }) }),
|
|
1532
|
+
show("alignRight") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyRight"), title: "Align right", active: fmt.aR, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "right" }) }),
|
|
1533
|
+
show("alignJustify") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("justifyFull"), title: "Justify", active: fmt.aJ, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AlignIco, { t: "justify" }) }),
|
|
1534
|
+
(show("alignLeft") || show("alignCenter") || show("alignRight") || show("alignJustify")) && (show("bulletList") || show("numberedList") || show("indent") || show("outdent")) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1535
|
+
show("bulletList") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("insertUnorderedList"), title: "Bullet list", active: fmt.ul, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoUL, {}) }),
|
|
1536
|
+
show("numberedList") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("insertOrderedList"), title: "Numbered list", active: fmt.ol, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoOL, {}) }),
|
|
1537
|
+
show("indent") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("indent"), title: "Indent (Tab)", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoIndent, {}) }),
|
|
1538
|
+
show("outdent") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("outdent"), title: "Outdent (Shift+Tab)", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoOutdent, {}) }),
|
|
1539
|
+
(show("bulletList") || show("numberedList") || show("indent") || show("outdent")) && (show("link") || show("codeBlock") || show("image") || show("table")) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {}),
|
|
1540
|
+
show("link") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: openLinkBar, title: "Insert link", active: linkBar, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoLink, {}) }),
|
|
1541
|
+
show("codeBlock") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: insertCodeBlock, title: "Code block", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoCode, {}) }),
|
|
1542
|
+
show("image") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1542
1543
|
showImagePicker && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: backdrop, onMouseDown: () => setShowImagePicker(false) }),
|
|
1543
1544
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => setShowImagePicker((v) => !v), title: "Insert image", active: showImagePicker, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoImage, {}) }),
|
|
1544
1545
|
showImagePicker && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { position: "absolute", top: 34, left: 0, zIndex: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
@@ -1552,7 +1553,7 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1552
1553
|
}
|
|
1553
1554
|
) })
|
|
1554
1555
|
] }),
|
|
1555
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1556
|
+
show("table") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1556
1557
|
showTable && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: backdrop, onMouseDown: () => setShowTable(false) }),
|
|
1557
1558
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => setShowTable((v) => !v), title: "Insert table", active: showTable || !!fmt.inTable, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoTable, {}) }),
|
|
1558
1559
|
showTable && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { position: "absolute", top: 34, left: 0, zIndex: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
@@ -1566,19 +1567,10 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1566
1567
|
}
|
|
1567
1568
|
) })
|
|
1568
1569
|
] }),
|
|
1569
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {})
|
|
1570
|
+
(show("link") || show("codeBlock") || show("image") || show("table")) && (show("html") || show("copyHtml")) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Sep, {})
|
|
1570
1571
|
] }),
|
|
1571
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1572
|
-
|
|
1573
|
-
{
|
|
1574
|
-
onClick: isCode ? toVisual : toCode,
|
|
1575
|
-
title: "Toggle HTML",
|
|
1576
|
-
active: isCode,
|
|
1577
|
-
style: { fontSize: 12, fontWeight: 600, letterSpacing: "0.03em", padding: "0 8px" },
|
|
1578
|
-
children: isCode ? "Visual" : "HTML"
|
|
1579
|
-
}
|
|
1580
|
-
),
|
|
1581
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: copyHtml, title: "Copy HTML", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoCopy, {}) }),
|
|
1572
|
+
show("html") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: isCode ? toVisual : toCode, title: "Toggle HTML", active: isCode, style: { fontSize: 12, fontWeight: 600, letterSpacing: "0.03em", padding: "0 8px" }, children: isCode ? "Visual" : "HTML" }),
|
|
1573
|
+
show("copyHtml") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: copyHtml, title: "Copy HTML", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IcoCopy, {}) }),
|
|
1582
1574
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1 } }),
|
|
1583
1575
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { fontSize: 12, color: "#aaa" }, children: [
|
|
1584
1576
|
words,
|
package/dist/index.mjs
CHANGED
|
@@ -1088,7 +1088,7 @@ function ImageEditor({ img, containerRef, onClose, onDelete, onChange }) {
|
|
|
1088
1088
|
|
|
1089
1089
|
// src/RichTextEditor.tsx
|
|
1090
1090
|
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1091
|
-
function RichTextEditor({ value, onChange }) {
|
|
1091
|
+
function RichTextEditor({ value, onChange, toolbar }) {
|
|
1092
1092
|
var _a;
|
|
1093
1093
|
const editorRef = useRef4(null);
|
|
1094
1094
|
const editorAreaRef = useRef4(null);
|
|
@@ -1440,15 +1440,16 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1440
1440
|
const canMerge = selCells.length >= 2;
|
|
1441
1441
|
const canSplit = fmt.cellMerged;
|
|
1442
1442
|
const backdrop = { position: "fixed", inset: 0, zIndex: 199 };
|
|
1443
|
+
const show = (key) => !toolbar || toolbar.includes(key);
|
|
1443
1444
|
return /* @__PURE__ */ jsxs6("div", { style: { padding: "1rem 0" }, children: [
|
|
1444
1445
|
/* @__PURE__ */ jsx7("style", { children: CSS }),
|
|
1445
1446
|
/* @__PURE__ */ jsxs6("div", { style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
|
|
1446
1447
|
/* @__PURE__ */ jsxs6("div", { className: "rte-toolbar", children: [
|
|
1447
1448
|
!isCode && /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1448
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
|
|
1449
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("italic"), title: "Italic (Ctrl+I)", active: fmt.italic, style: { fontStyle: "italic", fontFamily: "Georgia,serif" }, children: "I" }),
|
|
1450
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("underline"), title: "Underline (Ctrl+U)", active: fmt.underline, style: { textDecoration: "underline" }, children: "U" }),
|
|
1451
|
-
/* @__PURE__ */ jsxs6("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1449
|
+
show("bold") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
|
|
1450
|
+
show("italic") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("italic"), title: "Italic (Ctrl+I)", active: fmt.italic, style: { fontStyle: "italic", fontFamily: "Georgia,serif" }, children: "I" }),
|
|
1451
|
+
show("underline") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("underline"), title: "Underline (Ctrl+U)", active: fmt.underline, style: { textDecoration: "underline" }, children: "U" }),
|
|
1452
|
+
show("color") && /* @__PURE__ */ jsxs6("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1452
1453
|
showColor && /* @__PURE__ */ jsx7("div", { style: backdrop, onMouseDown: () => setShowColor(false) }),
|
|
1453
1454
|
/* @__PURE__ */ jsxs6(
|
|
1454
1455
|
Btn,
|
|
@@ -1480,8 +1481,8 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1480
1481
|
}
|
|
1481
1482
|
) })
|
|
1482
1483
|
] }),
|
|
1483
|
-
/* @__PURE__ */ jsx7(Sep, {}),
|
|
1484
|
-
/* @__PURE__ */ jsxs6(
|
|
1484
|
+
(show("bold") || show("italic") || show("underline") || show("color")) && (show("blockFormat") || show("alignLeft") || show("alignCenter") || show("alignRight") || show("alignJustify")) && /* @__PURE__ */ jsx7(Sep, {}),
|
|
1485
|
+
show("blockFormat") && /* @__PURE__ */ jsxs6(
|
|
1485
1486
|
"select",
|
|
1486
1487
|
{
|
|
1487
1488
|
className: "rte-select",
|
|
@@ -1504,20 +1505,20 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1504
1505
|
]
|
|
1505
1506
|
}
|
|
1506
1507
|
),
|
|
1507
|
-
/* @__PURE__ */ jsx7(Sep, {}),
|
|
1508
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyLeft"), title: "Align left", active: fmt.aL, children: /* @__PURE__ */ jsx7(AlignIco, { t: "left" }) }),
|
|
1509
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyCenter"), title: "Align center", active: fmt.aC, children: /* @__PURE__ */ jsx7(AlignIco, { t: "center" }) }),
|
|
1510
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyRight"), title: "Align right", active: fmt.aR, children: /* @__PURE__ */ jsx7(AlignIco, { t: "right" }) }),
|
|
1511
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyFull"), title: "Justify", active: fmt.aJ, children: /* @__PURE__ */ jsx7(AlignIco, { t: "justify" }) }),
|
|
1512
|
-
/* @__PURE__ */ jsx7(Sep, {}),
|
|
1513
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("insertUnorderedList"), title: "Bullet list", active: fmt.ul, children: /* @__PURE__ */ jsx7(IcoUL, {}) }),
|
|
1514
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("insertOrderedList"), title: "Numbered list", active: fmt.ol, children: /* @__PURE__ */ jsx7(IcoOL, {}) }),
|
|
1515
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("indent"), title: "Indent (Tab)", children: /* @__PURE__ */ jsx7(IcoIndent, {}) }),
|
|
1516
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: () => exec("outdent"), title: "Outdent (Shift+Tab)", children: /* @__PURE__ */ jsx7(IcoOutdent, {}) }),
|
|
1517
|
-
/* @__PURE__ */ jsx7(Sep, {}),
|
|
1518
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: openLinkBar, title: "Insert link", active: linkBar, children: /* @__PURE__ */ jsx7(IcoLink, {}) }),
|
|
1519
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: insertCodeBlock, title: "Code block", children: /* @__PURE__ */ jsx7(IcoCode, {}) }),
|
|
1520
|
-
/* @__PURE__ */ jsxs6("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1508
|
+
show("blockFormat") && (show("alignLeft") || show("alignCenter") || show("alignRight") || show("alignJustify")) && /* @__PURE__ */ jsx7(Sep, {}),
|
|
1509
|
+
show("alignLeft") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyLeft"), title: "Align left", active: fmt.aL, children: /* @__PURE__ */ jsx7(AlignIco, { t: "left" }) }),
|
|
1510
|
+
show("alignCenter") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyCenter"), title: "Align center", active: fmt.aC, children: /* @__PURE__ */ jsx7(AlignIco, { t: "center" }) }),
|
|
1511
|
+
show("alignRight") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyRight"), title: "Align right", active: fmt.aR, children: /* @__PURE__ */ jsx7(AlignIco, { t: "right" }) }),
|
|
1512
|
+
show("alignJustify") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("justifyFull"), title: "Justify", active: fmt.aJ, children: /* @__PURE__ */ jsx7(AlignIco, { t: "justify" }) }),
|
|
1513
|
+
(show("alignLeft") || show("alignCenter") || show("alignRight") || show("alignJustify")) && (show("bulletList") || show("numberedList") || show("indent") || show("outdent")) && /* @__PURE__ */ jsx7(Sep, {}),
|
|
1514
|
+
show("bulletList") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("insertUnorderedList"), title: "Bullet list", active: fmt.ul, children: /* @__PURE__ */ jsx7(IcoUL, {}) }),
|
|
1515
|
+
show("numberedList") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("insertOrderedList"), title: "Numbered list", active: fmt.ol, children: /* @__PURE__ */ jsx7(IcoOL, {}) }),
|
|
1516
|
+
show("indent") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("indent"), title: "Indent (Tab)", children: /* @__PURE__ */ jsx7(IcoIndent, {}) }),
|
|
1517
|
+
show("outdent") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("outdent"), title: "Outdent (Shift+Tab)", children: /* @__PURE__ */ jsx7(IcoOutdent, {}) }),
|
|
1518
|
+
(show("bulletList") || show("numberedList") || show("indent") || show("outdent")) && (show("link") || show("codeBlock") || show("image") || show("table")) && /* @__PURE__ */ jsx7(Sep, {}),
|
|
1519
|
+
show("link") && /* @__PURE__ */ jsx7(Btn, { onClick: openLinkBar, title: "Insert link", active: linkBar, children: /* @__PURE__ */ jsx7(IcoLink, {}) }),
|
|
1520
|
+
show("codeBlock") && /* @__PURE__ */ jsx7(Btn, { onClick: insertCodeBlock, title: "Code block", children: /* @__PURE__ */ jsx7(IcoCode, {}) }),
|
|
1521
|
+
show("image") && /* @__PURE__ */ jsxs6("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1521
1522
|
showImagePicker && /* @__PURE__ */ jsx7("div", { style: backdrop, onMouseDown: () => setShowImagePicker(false) }),
|
|
1522
1523
|
/* @__PURE__ */ jsx7(Btn, { onClick: () => setShowImagePicker((v) => !v), title: "Insert image", active: showImagePicker, children: /* @__PURE__ */ jsx7(IcoImage, {}) }),
|
|
1523
1524
|
showImagePicker && /* @__PURE__ */ jsx7("div", { style: { position: "absolute", top: 34, left: 0, zIndex: 200 }, children: /* @__PURE__ */ jsx7(
|
|
@@ -1531,7 +1532,7 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1531
1532
|
}
|
|
1532
1533
|
) })
|
|
1533
1534
|
] }),
|
|
1534
|
-
/* @__PURE__ */ jsxs6("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1535
|
+
show("table") && /* @__PURE__ */ jsxs6("div", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
1535
1536
|
showTable && /* @__PURE__ */ jsx7("div", { style: backdrop, onMouseDown: () => setShowTable(false) }),
|
|
1536
1537
|
/* @__PURE__ */ jsx7(Btn, { onClick: () => setShowTable((v) => !v), title: "Insert table", active: showTable || !!fmt.inTable, children: /* @__PURE__ */ jsx7(IcoTable, {}) }),
|
|
1537
1538
|
showTable && /* @__PURE__ */ jsx7("div", { style: { position: "absolute", top: 34, left: 0, zIndex: 200 }, children: /* @__PURE__ */ jsx7(
|
|
@@ -1545,19 +1546,10 @@ function RichTextEditor({ value, onChange }) {
|
|
|
1545
1546
|
}
|
|
1546
1547
|
) })
|
|
1547
1548
|
] }),
|
|
1548
|
-
/* @__PURE__ */ jsx7(Sep, {})
|
|
1549
|
+
(show("link") || show("codeBlock") || show("image") || show("table")) && (show("html") || show("copyHtml")) && /* @__PURE__ */ jsx7(Sep, {})
|
|
1549
1550
|
] }),
|
|
1550
|
-
/* @__PURE__ */ jsx7(
|
|
1551
|
-
|
|
1552
|
-
{
|
|
1553
|
-
onClick: isCode ? toVisual : toCode,
|
|
1554
|
-
title: "Toggle HTML",
|
|
1555
|
-
active: isCode,
|
|
1556
|
-
style: { fontSize: 12, fontWeight: 600, letterSpacing: "0.03em", padding: "0 8px" },
|
|
1557
|
-
children: isCode ? "Visual" : "HTML"
|
|
1558
|
-
}
|
|
1559
|
-
),
|
|
1560
|
-
/* @__PURE__ */ jsx7(Btn, { onClick: copyHtml, title: "Copy HTML", children: /* @__PURE__ */ jsx7(IcoCopy, {}) }),
|
|
1551
|
+
show("html") && /* @__PURE__ */ jsx7(Btn, { onClick: isCode ? toVisual : toCode, title: "Toggle HTML", active: isCode, style: { fontSize: 12, fontWeight: 600, letterSpacing: "0.03em", padding: "0 8px" }, children: isCode ? "Visual" : "HTML" }),
|
|
1552
|
+
show("copyHtml") && /* @__PURE__ */ jsx7(Btn, { onClick: copyHtml, title: "Copy HTML", children: /* @__PURE__ */ jsx7(IcoCopy, {}) }),
|
|
1561
1553
|
/* @__PURE__ */ jsx7("div", { style: { flex: 1 } }),
|
|
1562
1554
|
/* @__PURE__ */ jsxs6("span", { style: { fontSize: 12, color: "#aaa" }, children: [
|
|
1563
1555
|
words,
|