rj-editor 0.1.1 → 1.0.1
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 +291 -20
- package/dist/assets/icons/AttachmentIcon01.d.ts +2 -0
- package/dist/assets/icons/BorderRadiusIcon.d.ts +2 -0
- package/dist/assets/icons/ChevronSelectorHorizontalIcon.d.ts +2 -0
- package/dist/assets/icons/ChevronSelectorVerticalIcon.d.ts +2 -0
- package/dist/assets/icons/ImageIcon03.d.ts +2 -0
- package/dist/assets/icons/ImageIdentLeftIcon.d.ts +2 -0
- package/dist/assets/icons/ImageWrapTopBottomIcon.d.ts +2 -0
- package/dist/assets/icons/LayoutGridIcon01.d.ts +2 -0
- package/dist/assets/icons/LeftIndentIcon01.d.ts +2 -0
- package/dist/assets/icons/LineHeightIcon.d.ts +2 -0
- package/dist/assets/icons/MaximizeIcon02.d.ts +2 -0
- package/dist/assets/icons/MinimizeIcon02.d.ts +2 -0
- package/dist/assets/icons/PaintPourIcon.d.ts +2 -0
- package/dist/assets/icons/PaletteIcon.d.ts +2 -0
- package/dist/assets/icons/ParagraphSpacingIco.d.ts +2 -0
- package/dist/assets/icons/RefreshCcwIcon01.d.ts +2 -0
- package/dist/assets/icons/RefreshCcwIcon05.d.ts +2 -0
- package/dist/assets/icons/RefreshCwIcon01.d.ts +2 -0
- package/dist/assets/icons/RightIndentIcon01.d.ts +2 -0
- package/dist/assets/icons/SubscriptIcon.d.ts +2 -0
- package/dist/assets/icons/SupscriptIcon.d.ts +2 -0
- package/dist/assets/icons/TrashIcon03.d.ts +2 -0
- package/dist/assets/icons/VerticalAlignBottomIcon.d.ts +2 -0
- package/dist/assets/icons/VerticalAlignMiddleIcon.d.ts +2 -0
- package/dist/assets/icons/VerticalAlignTopIcon.d.ts +2 -0
- package/dist/assets/icons/YoutubeIcon.d.ts +2 -0
- package/dist/components/RJTextEditor.d.ts +3 -9
- package/dist/components/equation/EquationComponent.d.ts +10 -0
- package/dist/components/global/input-number/InputNumber.d.ts +14 -0
- package/dist/components/global/input-number/index.d.ts +2 -0
- package/dist/components/global/modal/Modal.d.ts +12 -0
- package/dist/components/global/modal/index.d.ts +2 -0
- package/dist/components/image/ImageComponent.d.ts +21 -0
- package/dist/components/rj-text-editor/HtmlValuePlugin.d.ts +7 -0
- package/dist/components/rj-text-editor/RJTextEditor.types.d.ts +18 -0
- package/dist/components/rj-text-editor/RJTextEditorContent.d.ts +17 -0
- package/dist/components/rj-text-editor/createInitialConfig.d.ts +47 -0
- package/dist/components/rj-text-editor/editorTheme.d.ts +26 -0
- package/dist/components/rj-text-editor/handleEditorChange.d.ts +3 -0
- package/dist/components/toolbar/Toolbar.d.ts +6 -1
- package/dist/components/toolbar/equation/EquationToolbar.d.ts +1 -0
- package/dist/components/toolbar/equation/utils.d.ts +13 -0
- package/dist/components/toolbar/home/HomeToolbar.d.ts +6 -0
- package/dist/components/toolbar/home/indent/IndentControls.d.ts +1 -0
- package/dist/components/toolbar/home/spacing/SpacingControls.d.ts +1 -0
- package/dist/components/toolbar/image/ImageToolbar.d.ts +2 -0
- package/dist/components/toolbar/image/divider/ToolbarDivider.d.ts +1 -0
- package/dist/components/toolbar/image/utils.d.ts +26 -0
- package/dist/components/toolbar/insert/InsertToolbar.d.ts +5 -0
- package/dist/components/toolbar/insert/divider/ToolbarDivider.d.ts +1 -0
- package/dist/components/toolbar/insert/equation/EquationControl.d.ts +2 -0
- package/dist/components/toolbar/insert/equation/EquationExamples.d.ts +6 -0
- package/dist/components/toolbar/insert/equation/EquationModal.d.ts +11 -0
- package/dist/components/toolbar/insert/equation/EquationPreview.d.ts +8 -0
- package/dist/components/toolbar/insert/horizontal-rule/HorizontalRuleControl.d.ts +1 -0
- package/dist/components/toolbar/insert/image/ImageControl.d.ts +1 -0
- package/dist/components/toolbar/insert/link/LinkControl.d.ts +7 -0
- package/dist/components/toolbar/insert/table/TableControl.d.ts +5 -0
- package/dist/components/toolbar/insert/youtube/YouTubeControl.d.ts +2 -0
- package/dist/components/toolbar/layout/LayoutToolbar.d.ts +1 -0
- package/dist/components/toolbar/table/TableToolbar.d.ts +1 -0
- package/dist/components/toolbar/table/cell/CellControls.d.ts +1 -0
- package/dist/components/toolbar/table/columns/ColumnControls.d.ts +1 -0
- package/dist/components/toolbar/table/delete/DeleteTableControls.d.ts +1 -0
- package/dist/components/toolbar/table/divider/ToolbarDivider.d.ts +1 -0
- package/dist/components/toolbar/table/header-cell/HeaderCellControls.d.ts +1 -0
- package/dist/components/toolbar/table/merge/MergeControls.d.ts +1 -0
- package/dist/components/toolbar/table/rows/RowControls.d.ts +1 -0
- package/dist/components/toolbar/table/utils.d.ts +23 -0
- package/dist/components/youtube/YouTubeComponent.d.ts +9 -0
- package/dist/constants/equationEditorEventName.d.ts +1 -0
- package/dist/constants/equationExamples.d.ts +16 -0
- package/dist/constants/equationStructures.d.ts +33 -0
- package/dist/constants/equationSymbols.d.ts +1 -0
- package/dist/constants/index.d.ts +10 -0
- package/dist/constants/initialToolbarState.d.ts +1 -1
- package/dist/constants/insertEquationCommand.d.ts +2 -0
- package/dist/constants/insertImageCommand.d.ts +2 -0
- package/dist/constants/insertYouTubeCommand.d.ts +2 -0
- package/dist/constants/lineHeightOptions.d.ts +1 -0
- package/dist/constants/maxImageFileSize.d.ts +1 -0
- package/dist/constants/openLinkModalEventName.d.ts +1 -0
- package/dist/i18n/I18nContext.d.ts +9 -0
- package/dist/i18n/RJEditorI18nContext.d.ts +3 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/locales/en.d.ts +2 -0
- package/dist/i18n/locales/ru.d.ts +2 -0
- package/dist/i18n/locales/uz.d.ts +2 -0
- package/dist/i18n/mergeTranslations.d.ts +2 -0
- package/dist/i18n/useRJEditorI18n.d.ts +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/nodes/EquationNode.d.ts +26 -0
- package/dist/nodes/ExtendedTextNode.d.ts +12 -0
- package/dist/nodes/ImageNode.d.ts +62 -0
- package/dist/nodes/YouTubeNode.d.ts +25 -0
- package/dist/nodes/index.d.ts +4 -0
- package/dist/plugins/EquationPlugin.d.ts +1 -0
- package/dist/plugins/ImagePlugin.d.ts +1 -0
- package/dist/plugins/KeyboardShortcutsPlugin.d.ts +1 -0
- package/dist/plugins/TableBoundaryPlugin.d.ts +1 -0
- package/dist/plugins/YouTubePlugin.d.ts +1 -0
- package/dist/rj-editor.css +1 -1
- package/dist/rj-editor.js +32116 -555
- package/dist/rj-editor.umd.cjs +259 -1
- package/dist/slice/index.d.ts +1 -1
- package/dist/slice/toolbarSlice.d.ts +2 -2
- package/dist/store/hooks.d.ts +2 -2
- package/dist/store/index.d.ts +1 -1
- package/dist/types/AppDispatch.d.ts +1 -1
- package/dist/types/DeepPartial.d.ts +3 -0
- package/dist/types/EquationDisplayMode.d.ts +1 -0
- package/dist/types/ImageAlignment.d.ts +1 -0
- package/dist/types/ImageObjectFit.d.ts +1 -0
- package/dist/types/ImageTextWrap.d.ts +1 -0
- package/dist/types/InsertEquationPayload.d.ts +5 -0
- package/dist/types/InsertImagePayload.d.ts +19 -0
- package/dist/types/InsertYouTubePayload.d.ts +4 -0
- package/dist/types/RJEditorLocaleCode.d.ts +1 -0
- package/dist/types/RJEditorTranslations.d.ts +173 -0
- package/dist/types/RootState.d.ts +1 -1
- package/dist/types/SerializedEquationNode.d.ts +6 -0
- package/dist/types/SerializedImageNode.d.ts +20 -0
- package/dist/types/SerializedYouTubeNode.d.ts +5 -0
- package/dist/types/ToolbarState.d.ts +35 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/utils/helpers/clampValue.d.ts +1 -0
- package/dist/utils/helpers/formatNumberText.d.ts +1 -0
- package/dist/utils/helpers/formatShortcutTitle.d.ts +1 -0
- package/dist/utils/helpers/getYouTubeVideoId.d.ts +1 -0
- package/dist/utils/helpers/index.d.ts +12 -0
- package/dist/utils/helpers/isApplePlatform.d.ts +1 -0
- package/dist/utils/helpers/normalizeNumberText.d.ts +1 -0
- package/dist/utils/helpers/normalizeRJEditorHtml.d.ts +2 -0
- package/dist/utils/helpers/numberToInputText.d.ts +1 -0
- package/dist/utils/helpers/openFilePicker.d.ts +1 -0
- package/dist/utils/helpers/readFileAsDataUrl.d.ts +1 -0
- package/dist/utils/helpers/renderEquationToHtml.d.ts +3 -0
- package/dist/utils/helpers/setEditorHtml.d.ts +2 -0
- package/package.json +34 -2
- /package/dist/components/toolbar/{alignment → home/alignment}/AlignmentControls.d.ts +0 -0
- /package/dist/components/toolbar/{divider → home/divider}/ToolbarDivider.d.ts +0 -0
- /package/dist/components/toolbar/{history → home/history}/HistoryControls.d.ts +0 -0
- /package/dist/components/toolbar/{list → home/list}/ListControls.d.ts +0 -0
- /package/dist/components/toolbar/{style-controls → home/style-controls}/StyleControls.d.ts +0 -0
- /package/dist/components/toolbar/{style-controls → home/style-controls}/background-color/BackgroundColorControl.d.ts +0 -0
- /package/dist/components/toolbar/{style-controls → home/style-controls}/clear-formatting/ClearFormattingControl.d.ts +0 -0
- /package/dist/components/toolbar/{style-controls → home/style-controls}/font-family/FontFamilyControl.d.ts +0 -0
- /package/dist/components/toolbar/{style-controls → home/style-controls}/font-size/FontSizeControl.d.ts +0 -0
- /package/dist/components/toolbar/{style-controls → home/style-controls}/text-color/TextColorControl.d.ts +0 -0
- /package/dist/components/toolbar/{style-controls → home/style-controls}/utils.d.ts +0 -0
- /package/dist/components/toolbar/{text-format → home/text-format}/TextFormatControls.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,51 +1,322 @@
|
|
|
1
1
|
# RJ Editor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`rj-editor` is a React rich text editor package for building article editors, admin panels, CMS forms, learning platforms, notes, documentation tools, and other content-heavy interfaces.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It provides a ready-to-use `RJTextEditor` component with a tabbed toolbar, text formatting, tables, links, images, YouTube embeds, fullscreen mode, i18n, theming, and Ant Design Form support.
|
|
6
|
+
|
|
7
|
+
[Live demo](https://rj-editor.vercel.app)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Text formatting: bold, italic, underline, strikethrough, subscript, superscript.
|
|
12
|
+
- Style controls: font size, font family, text color, background color, clear formatting.
|
|
13
|
+
- Paragraph tools: alignment, ordered list, unordered list, indent, outdent, line and paragraph spacing.
|
|
14
|
+
- Insert tools: table, link, image, YouTube video.
|
|
15
|
+
- Table editing: add/remove rows and columns, merge/split cells, header row/column, cell background, vertical alignment, delete table.
|
|
16
|
+
- Image editing: upload, drag-and-drop, paste from clipboard, resize, align, alt text, caption, link, border, border radius, shadow, object fit, wrapping, rotate, replace, delete.
|
|
17
|
+
- Browser fullscreen mode.
|
|
18
|
+
- Ant Design `Form.Item` integration.
|
|
19
|
+
- Built-in `uz`, `en`, and `ru` translations.
|
|
20
|
+
- Custom locale and partial translation override support.
|
|
21
|
+
- Theme customization through CSS custom properties.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
6
24
|
|
|
7
25
|
```bash
|
|
8
26
|
npm install rj-editor
|
|
9
27
|
```
|
|
10
28
|
|
|
11
|
-
|
|
29
|
+
`react` and `react-dom` are peer dependencies. They must already exist in your application:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install react react-dom
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
12
36
|
|
|
13
37
|
```tsx
|
|
14
38
|
import { RJTextEditor } from 'rj-editor'
|
|
15
|
-
import 'rj-editor/style.css'
|
|
16
39
|
|
|
17
40
|
export function App() {
|
|
18
41
|
return (
|
|
19
42
|
<RJTextEditor
|
|
20
43
|
autofocus
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
44
|
+
locale="en"
|
|
45
|
+
placeholder="Write your content..."
|
|
46
|
+
onChange={(html) => {
|
|
47
|
+
console.log(html)
|
|
24
48
|
}}
|
|
25
|
-
placeholder="Matn yozing..."
|
|
26
49
|
/>
|
|
27
50
|
)
|
|
28
51
|
}
|
|
29
52
|
```
|
|
30
53
|
|
|
31
|
-
|
|
54
|
+
You do not need to import a separate stylesheet. The package styles are included when `RJTextEditor` is imported.
|
|
55
|
+
|
|
56
|
+
## Saving Content
|
|
57
|
+
|
|
58
|
+
`onChange` returns the editor content as an HTML string in the first argument. This is the value you usually store in your database.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
<RJTextEditor
|
|
62
|
+
onChange={(html) => {
|
|
63
|
+
saveDraft(html)
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The callback also exposes a JSON string and the current editor state for advanced use cases:
|
|
32
69
|
|
|
33
70
|
```ts
|
|
34
|
-
type
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
71
|
+
type OnChange = (
|
|
72
|
+
html: string,
|
|
73
|
+
json: string,
|
|
74
|
+
editorState: unknown,
|
|
75
|
+
) => void
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Initial Content
|
|
79
|
+
|
|
80
|
+
Use `defaultValue` when you want to load saved HTML once when the editor mounts:
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
<RJTextEditor defaultValue="<p>Hello world</p>" />
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use `value` when your application controls the editor content from React state:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { useState } from 'react'
|
|
90
|
+
import { RJTextEditor } from 'rj-editor'
|
|
91
|
+
|
|
92
|
+
export function ControlledEditor() {
|
|
93
|
+
const [content, setContent] = useState('<p>Initial content</p>')
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<RJTextEditor
|
|
97
|
+
value={content}
|
|
98
|
+
onChange={(html) => setContent(html)}
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
40
101
|
}
|
|
41
102
|
```
|
|
42
103
|
|
|
43
|
-
##
|
|
104
|
+
## Ant Design Form
|
|
44
105
|
|
|
45
|
-
|
|
106
|
+
`RJTextEditor` works inside Ant Design `Form.Item`. The form receives the HTML string as the field value.
|
|
46
107
|
|
|
47
|
-
```
|
|
48
|
-
import '
|
|
108
|
+
```tsx
|
|
109
|
+
import { Button, Form } from 'antd'
|
|
110
|
+
import { RJTextEditor } from 'rj-editor'
|
|
111
|
+
|
|
112
|
+
export function ArticleForm() {
|
|
113
|
+
return (
|
|
114
|
+
<Form
|
|
115
|
+
layout="vertical"
|
|
116
|
+
onFinish={(values) => {
|
|
117
|
+
console.log(values.content)
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
<Form.Item
|
|
121
|
+
label="Content"
|
|
122
|
+
name="content"
|
|
123
|
+
rules={[{ required: true, message: 'Content is required' }]}
|
|
124
|
+
>
|
|
125
|
+
<RJTextEditor placeholder="Write your article..." />
|
|
126
|
+
</Form.Item>
|
|
127
|
+
|
|
128
|
+
<Button htmlType="submit" type="primary">
|
|
129
|
+
Save
|
|
130
|
+
</Button>
|
|
131
|
+
</Form>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
49
134
|
```
|
|
50
135
|
|
|
51
|
-
|
|
136
|
+
When validation fails, the editor border follows the Ant Design error state.
|
|
137
|
+
|
|
138
|
+
## Props
|
|
139
|
+
|
|
140
|
+
| Prop | Type | Default | Description |
|
|
141
|
+
| --- | --- | --- | --- |
|
|
142
|
+
| `autofocus` | `boolean` | `false` | Focuses the editor after mount. |
|
|
143
|
+
| `className` | `string` | `undefined` | Adds a custom class to the editor root. |
|
|
144
|
+
| `defaultValue` | `string` | `undefined` | Initial HTML content. Applied once on mount. |
|
|
145
|
+
| `id` | `string` | `undefined` | Adds an `id` to the editor root. |
|
|
146
|
+
| `locale` | `'uz' \| 'en' \| 'ru' \| string` | `'uz'` | Active editor language. |
|
|
147
|
+
| `locales` | `Record<string, DeepPartial<RJEditorTranslations>>` | `undefined` | Adds custom locales. |
|
|
148
|
+
| `namespace` | `string` | `'RJEditor'` | Unique editor namespace. Useful when multiple editor instances exist on one page. |
|
|
149
|
+
| `onBlur` | `React.FocusEventHandler<HTMLDivElement>` | `undefined` | Called when the editor root loses focus. |
|
|
150
|
+
| `onChange` | `(html, json, editorState) => void` | `undefined` | Called whenever editor content changes. |
|
|
151
|
+
| `onFocus` | `React.FocusEventHandler<HTMLDivElement>` | `undefined` | Called when the editor root receives focus. |
|
|
152
|
+
| `placeholder` | `string` | Locale-based text | Placeholder shown when the editor is empty. |
|
|
153
|
+
| `translations` | `DeepPartial<RJEditorTranslations>` | `undefined` | Overrides translations for the active locale. |
|
|
154
|
+
| `value` | `string` | `undefined` | Controlled HTML content. |
|
|
155
|
+
|
|
156
|
+
## Toolbar
|
|
157
|
+
|
|
158
|
+
The toolbar is organized by tabs:
|
|
159
|
+
|
|
160
|
+
- `Home`: text formatting, styles, lists, alignment, indentation, and spacing.
|
|
161
|
+
- `Insert`: table, link, image, and YouTube video insertion.
|
|
162
|
+
- `Image`: shown when an image is selected.
|
|
163
|
+
- `Table`: shown when the cursor is inside a table.
|
|
164
|
+
|
|
165
|
+
Contextual tabs are only visible when they are useful, keeping the editor interface focused.
|
|
166
|
+
|
|
167
|
+
## Images
|
|
168
|
+
|
|
169
|
+
Images can be inserted from the local file picker, drag-and-drop, or clipboard paste. The image is stored as a base64 data URL inside the editor content.
|
|
170
|
+
|
|
171
|
+
Important details:
|
|
172
|
+
|
|
173
|
+
- Maximum image size is `5MB`.
|
|
174
|
+
- Base64 images increase HTML size.
|
|
175
|
+
- For large production systems, a server upload flow or storage adapter is recommended.
|
|
176
|
+
|
|
177
|
+
Image tools include:
|
|
178
|
+
|
|
179
|
+
- left, center, and right alignment;
|
|
180
|
+
- custom width percentage;
|
|
181
|
+
- quick resize: 25%, 50%, 100%;
|
|
182
|
+
- alt text;
|
|
183
|
+
- caption;
|
|
184
|
+
- link;
|
|
185
|
+
- border;
|
|
186
|
+
- border radius;
|
|
187
|
+
- shadow;
|
|
188
|
+
- object fit: contain, cover, fill;
|
|
189
|
+
- text wrapping: top-bottom and square;
|
|
190
|
+
- rotate left/right;
|
|
191
|
+
- replace image;
|
|
192
|
+
- delete image.
|
|
193
|
+
|
|
194
|
+
## Tables
|
|
195
|
+
|
|
196
|
+
Tables can be created from the `Insert` tab with a grid picker or by entering row and column counts.
|
|
197
|
+
|
|
198
|
+
Available table tools:
|
|
199
|
+
|
|
200
|
+
- add row above/below;
|
|
201
|
+
- add column left/right;
|
|
202
|
+
- delete row/column;
|
|
203
|
+
- merge cells;
|
|
204
|
+
- split cells;
|
|
205
|
+
- toggle header row;
|
|
206
|
+
- toggle header column;
|
|
207
|
+
- set cell background;
|
|
208
|
+
- set vertical alignment;
|
|
209
|
+
- delete table.
|
|
210
|
+
|
|
211
|
+
## Links
|
|
212
|
+
|
|
213
|
+
Links are created with a custom modal. The modal supports URL and display text fields and works correctly in fullscreen mode.
|
|
214
|
+
|
|
215
|
+
## YouTube Embeds
|
|
216
|
+
|
|
217
|
+
Paste a YouTube URL from the `Insert` tab to add an embedded video. The editor converts supported YouTube links into an iframe embed.
|
|
218
|
+
|
|
219
|
+
## Fullscreen
|
|
220
|
+
|
|
221
|
+
The fullscreen button uses the browser Fullscreen API. The editor is opened in real fullscreen mode, not only enlarged with CSS.
|
|
222
|
+
|
|
223
|
+
## Internationalization
|
|
224
|
+
|
|
225
|
+
Built-in locales:
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
<RJTextEditor locale="uz" />
|
|
229
|
+
<RJTextEditor locale="en" />
|
|
230
|
+
<RJTextEditor locale="ru" />
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Override only the text you need:
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
<RJTextEditor
|
|
237
|
+
locale="en"
|
|
238
|
+
translations={{
|
|
239
|
+
placeholders: {
|
|
240
|
+
editor: 'Start writing...',
|
|
241
|
+
},
|
|
242
|
+
}}
|
|
243
|
+
/>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Add a custom locale:
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
<RJTextEditor
|
|
250
|
+
locale="kaa"
|
|
251
|
+
locales={{
|
|
252
|
+
kaa: {
|
|
253
|
+
placeholders: {
|
|
254
|
+
editor: 'Maqalanı usı jerge jazıń...',
|
|
255
|
+
},
|
|
256
|
+
tabs: {
|
|
257
|
+
home: 'Bas bet',
|
|
258
|
+
insert: 'Qosıw',
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
}}
|
|
262
|
+
/>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Theme
|
|
266
|
+
|
|
267
|
+
`rj-editor` exposes CSS custom properties. Override them in your application stylesheet to match your design system.
|
|
268
|
+
|
|
269
|
+
```css
|
|
270
|
+
:root {
|
|
271
|
+
--rj-color-brand: #2563eb;
|
|
272
|
+
--rj-color-brand-tint: #eaf2ff;
|
|
273
|
+
--rj-color-surface: #ffffff;
|
|
274
|
+
--rj-color-surface-soft: #f8fafc;
|
|
275
|
+
--rj-color-border: #d9dde5;
|
|
276
|
+
--rj-color-text: #111827;
|
|
277
|
+
|
|
278
|
+
--rj-editor-bg: var(--rj-color-surface);
|
|
279
|
+
--rj-editor-border: var(--rj-color-border);
|
|
280
|
+
--rj-editor-text: var(--rj-color-text);
|
|
281
|
+
--rj-editor-toolbar-bg: var(--rj-color-surface-soft);
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Common variables:
|
|
286
|
+
|
|
287
|
+
| Variable | Description |
|
|
288
|
+
| --- | --- |
|
|
289
|
+
| `--rj-editor-bg` | Editor content background. |
|
|
290
|
+
| `--rj-editor-border` | Editor border color. |
|
|
291
|
+
| `--rj-editor-text` | Main text color. |
|
|
292
|
+
| `--rj-editor-placeholder` | Placeholder color. |
|
|
293
|
+
| `--rj-editor-toolbar-bg` | Toolbar background. |
|
|
294
|
+
| `--rj-editor-toolbar-button-bg` | Toolbar button background. |
|
|
295
|
+
| `--rj-editor-toolbar-button-active-bg` | Active toolbar button background. |
|
|
296
|
+
| `--rj-editor-link` | Link color. |
|
|
297
|
+
| `--rj-editor-focus-border` | Focus border color. |
|
|
298
|
+
| `--rj-editor-error-border` | Validation error border color. |
|
|
299
|
+
| `--rj-editor-warning-border` | Validation warning border color. |
|
|
300
|
+
| `--rj-editor-table-border` | Table border color. |
|
|
301
|
+
| `--rj-editor-table-header-bg` | Table header background. |
|
|
302
|
+
| `--rj-editor-image-border` | Image selection border color. |
|
|
303
|
+
| `--rj-editor-danger` | Dangerous action color. |
|
|
304
|
+
|
|
305
|
+
## SSR
|
|
306
|
+
|
|
307
|
+
`rj-editor` depends on browser APIs such as DOM selection, clipboard, file input, and fullscreen. In SSR frameworks, render the editor only on the client.
|
|
308
|
+
|
|
309
|
+
Example for Next.js:
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
import dynamic from 'next/dynamic'
|
|
313
|
+
|
|
314
|
+
const RJTextEditor = dynamic(
|
|
315
|
+
() => import('rj-editor').then((mod) => mod.RJTextEditor),
|
|
316
|
+
{ ssr: false },
|
|
317
|
+
)
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## License
|
|
321
|
+
|
|
322
|
+
MIT
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RJTextEditorProps } from './rj-text-editor/RJTextEditor.types';
|
|
2
2
|
import './RJTextEditor.scss';
|
|
3
|
-
export type RJTextEditorProps
|
|
4
|
-
|
|
5
|
-
className?: string;
|
|
6
|
-
namespace?: string;
|
|
7
|
-
onChange?: (value: RJTextEditorValue) => void;
|
|
8
|
-
placeholder?: string;
|
|
9
|
-
};
|
|
10
|
-
export declare function RJTextEditor({ autofocus, className, namespace, onChange, placeholder, }: RJTextEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export type { RJTextEditorProps } from './rj-text-editor/RJTextEditor.types';
|
|
4
|
+
export declare function RJTextEditor({ autofocus, className, defaultValue, id, locale, locales, namespace, onBlur, onChange, onFocus, placeholder, translations, value, }: RJTextEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type NodeKey } from 'lexical';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { EquationDisplayMode } from '../../types/index';
|
|
4
|
+
type EquationComponentProps = {
|
|
5
|
+
displayMode: EquationDisplayMode;
|
|
6
|
+
equation: string;
|
|
7
|
+
nodeKey: NodeKey;
|
|
8
|
+
};
|
|
9
|
+
export declare const EquationComponent: React.MemoExoticComponent<({ displayMode, equation, nodeKey, }: EquationComponentProps) => import("react/jsx-runtime").JSX.Element>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type InputNumberProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'defaultValue' | 'inputMode' | 'onChange' | 'prefix' | 'suffix' | 'type' | 'value'> & {
|
|
3
|
+
decimalScale?: number;
|
|
4
|
+
defaultValue?: number;
|
|
5
|
+
integerOnly?: boolean;
|
|
6
|
+
locale?: boolean;
|
|
7
|
+
max?: number;
|
|
8
|
+
min?: number;
|
|
9
|
+
onChange?: (value: number) => void;
|
|
10
|
+
prefix?: React.ReactNode;
|
|
11
|
+
suffix?: React.ReactNode;
|
|
12
|
+
value?: number;
|
|
13
|
+
};
|
|
14
|
+
export default function InputNumber({ className, decimalScale, defaultValue, integerOnly, locale, max, min, onBlur, onChange, prefix, suffix, value, ...props }: InputNumberProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type ModalProps = {
|
|
3
|
+
cancelText?: string;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
okText?: string;
|
|
6
|
+
onCancel: () => void;
|
|
7
|
+
onOk?: () => void;
|
|
8
|
+
open: boolean;
|
|
9
|
+
title?: React.ReactNode;
|
|
10
|
+
width?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function Modal({ cancelText, children, okText, onCancel, onOk, open, title, width, }: ModalProps): React.ReactPortal | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type NodeKey } from 'lexical';
|
|
2
|
+
import type { ImageAlignment, ImageObjectFit, ImageTextWrap } from '../../types/index';
|
|
3
|
+
type ImageComponentProps = {
|
|
4
|
+
alignment: ImageAlignment;
|
|
5
|
+
altText: string;
|
|
6
|
+
aspectRatioLocked: boolean;
|
|
7
|
+
borderEnabled: boolean;
|
|
8
|
+
borderRadius: number;
|
|
9
|
+
caption: string;
|
|
10
|
+
height?: number;
|
|
11
|
+
linkUrl: string;
|
|
12
|
+
nodeKey: NodeKey;
|
|
13
|
+
objectFit: ImageObjectFit;
|
|
14
|
+
rotation: number;
|
|
15
|
+
shadowEnabled: boolean;
|
|
16
|
+
src: string;
|
|
17
|
+
textWrap: ImageTextWrap;
|
|
18
|
+
width: number;
|
|
19
|
+
};
|
|
20
|
+
export declare function ImageComponent({ alignment, altText, aspectRatioLocked, borderEnabled, borderRadius, caption, height, linkUrl, nodeKey, objectFit, rotation, shadowEnabled, src, textWrap, width, }: ImageComponentProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { EditorState } from 'lexical';
|
|
3
|
+
import type { DeepPartial, RJEditorLocaleCode, RJEditorTranslations } from '../../types/index';
|
|
4
|
+
export type RJTextEditorProps = {
|
|
5
|
+
autofocus?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
defaultValue?: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
namespace?: string;
|
|
10
|
+
onBlur?: React.FocusEventHandler<HTMLDivElement>;
|
|
11
|
+
onChange?: (html: string, json: string, editorState: EditorState) => void;
|
|
12
|
+
onFocus?: React.FocusEventHandler<HTMLDivElement>;
|
|
13
|
+
locale?: RJEditorLocaleCode;
|
|
14
|
+
locales?: Record<string, DeepPartial<RJEditorTranslations>>;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
translations?: DeepPartial<RJEditorTranslations>;
|
|
17
|
+
value?: string;
|
|
18
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { RJTextEditorProps } from './RJTextEditor.types';
|
|
3
|
+
type RJTextEditorContentProps = {
|
|
4
|
+
autofocus: boolean;
|
|
5
|
+
className?: string;
|
|
6
|
+
editorRef: React.RefObject<HTMLDivElement | null>;
|
|
7
|
+
id?: string;
|
|
8
|
+
isFullscreen: boolean;
|
|
9
|
+
onBlur?: React.FocusEventHandler<HTMLDivElement>;
|
|
10
|
+
onChange?: RJTextEditorProps['onChange'];
|
|
11
|
+
onFocus?: React.FocusEventHandler<HTMLDivElement>;
|
|
12
|
+
onToggleFullscreen: () => void;
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function RJTextEditorContent({ autofocus, className, editorRef, id, isFullscreen, onBlur, onChange, onFocus, onToggleFullscreen, placeholder, value, }: RJTextEditorContentProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { LinkNode } from '@lexical/link';
|
|
2
|
+
import { ListItemNode, ListNode } from '@lexical/list';
|
|
3
|
+
import { TableCellNode, TableNode, TableRowNode } from '@lexical/table';
|
|
4
|
+
import { TextNode, type LexicalEditor } from 'lexical';
|
|
5
|
+
import { EquationNode, ExtendedTextNode, ImageNode, YouTubeNode, replaceTextNodeWithExtendedTextNode } from '../../nodes/index';
|
|
6
|
+
type CreateInitialConfigOptions = {
|
|
7
|
+
defaultValue?: string;
|
|
8
|
+
namespace: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function createInitialConfig({ defaultValue, namespace, value, }: CreateInitialConfigOptions): {
|
|
12
|
+
namespace: string;
|
|
13
|
+
nodes: (typeof EquationNode | typeof ExtendedTextNode | typeof ImageNode | typeof YouTubeNode | typeof LinkNode | typeof ListNode | typeof ListItemNode | typeof TableCellNode | typeof TableNode | typeof TableRowNode | {
|
|
14
|
+
replace: typeof TextNode;
|
|
15
|
+
with: typeof replaceTextNodeWithExtendedTextNode;
|
|
16
|
+
withKlass: typeof ExtendedTextNode;
|
|
17
|
+
})[];
|
|
18
|
+
onError(error: Error): never;
|
|
19
|
+
editorState: ((editor: LexicalEditor) => void) | undefined;
|
|
20
|
+
theme: {
|
|
21
|
+
paragraph: string;
|
|
22
|
+
text: {
|
|
23
|
+
bold: string;
|
|
24
|
+
italic: string;
|
|
25
|
+
strikethrough: string;
|
|
26
|
+
subscript: string;
|
|
27
|
+
superscript: string;
|
|
28
|
+
underline: string;
|
|
29
|
+
};
|
|
30
|
+
list: {
|
|
31
|
+
ol: string;
|
|
32
|
+
ul: string;
|
|
33
|
+
listitem: string;
|
|
34
|
+
};
|
|
35
|
+
equation: string;
|
|
36
|
+
image: string;
|
|
37
|
+
youtube: string;
|
|
38
|
+
table: string;
|
|
39
|
+
tableCell: string;
|
|
40
|
+
tableCellHeader: string;
|
|
41
|
+
tableCellSelected: string;
|
|
42
|
+
tableRow: string;
|
|
43
|
+
tableScrollableWrapper: string;
|
|
44
|
+
tableSelection: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const editorTheme: {
|
|
2
|
+
paragraph: string;
|
|
3
|
+
text: {
|
|
4
|
+
bold: string;
|
|
5
|
+
italic: string;
|
|
6
|
+
strikethrough: string;
|
|
7
|
+
subscript: string;
|
|
8
|
+
superscript: string;
|
|
9
|
+
underline: string;
|
|
10
|
+
};
|
|
11
|
+
list: {
|
|
12
|
+
ol: string;
|
|
13
|
+
ul: string;
|
|
14
|
+
listitem: string;
|
|
15
|
+
};
|
|
16
|
+
equation: string;
|
|
17
|
+
image: string;
|
|
18
|
+
youtube: string;
|
|
19
|
+
table: string;
|
|
20
|
+
tableCell: string;
|
|
21
|
+
tableCellHeader: string;
|
|
22
|
+
tableCellSelected: string;
|
|
23
|
+
tableRow: string;
|
|
24
|
+
tableScrollableWrapper: string;
|
|
25
|
+
tableSelection: string;
|
|
26
|
+
};
|