@uxf/wysiwyg 12.7.0 → 13.0.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 CHANGED
@@ -18,7 +18,7 @@ All Plate/Slate packages and the UXF packages are **peer dependencies** with pin
18
18
 
19
19
  - UXF: `@uxf/core`, `@uxf/core-react`, `@uxf/ui`
20
20
  - Plate: `platejs` (`53.3.9`), `@platejs/basic-nodes` (`53.0.0`), `@platejs/floating` (`53.0.0`), `@platejs/link` (`53.3.5`), `@platejs/list-classic` (`53.0.0`), `@platejs/media` (`53.1.4`)
21
- - `react` / `react-dom` (`>=18.2.0`)
21
+ - `react` / `react-dom` (`^19.3.0`)
22
22
 
23
23
  `slate` and `slate-react` are deliberately **not** peer dependencies. Plate owns the whole Slate stack, and declaring them here made npm resolve a second physical copy of `slate-react` — two copies mean two React contexts and a silently broken `useSelected()`.
24
24
 
@@ -110,18 +110,18 @@ Everything below is exported from the package root (`@uxf/wysiwyg`) unless a dee
110
110
 
111
111
  `import { WysiwygEditor } from "@uxf/wysiwyg";`
112
112
 
113
- | Prop | Type | Required | Description |
114
- | ----------------------------- | ----------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115
- | `id` | `string` | yes | Unique Plate instance id. Must be unique per editor on the page. |
116
- | `initialValue` | `WysiwygContent \| undefined` | yes | Document the editor is seeded with on mount. |
117
- | `onChange` | `(value: WysiwygContent) => void` | yes | Called on every edit with the full document. |
118
- | `plugins` | `UxfPlatePlugin[]` | yes | Build with `createAllPluginsWithUi` / `createPluginsWithUi`. |
119
- | `className` | `string` | no | Class on the editor root wrapper. |
120
- | `editableProps` | `TEditableProps<WysiwygContent>` | no | Passed to Plate's editable area (`placeholder`, `readOnly`, `autoFocus`, `spellCheck`, `className`, …). Defaults: `autoFocus: false`, `readOnly: false`, `spellCheck: false`, localized placeholder. |
121
- | `editorRef` | `ForwardedRef<WysiwygEditorHandle>` | no | Imperative handle exposing `focus()`, which selects the end of the document and then focuses the editable area. |
122
- | `customPluginsToolbarButtons` | `ReactNode` | no | Extra toolbar buttons appended to the built-in ones. |
123
- | `toolbarLeftElement` | `ReactNode` | no | Node rendered at the toolbar's left edge. |
124
- | `toolbarRightElement` | `ReactNode` | no | Node rendered at the toolbar's right edge. |
113
+ | Prop | Type | Required | Description |
114
+ | ----------------------------- | --------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115
+ | `id` | `string` | yes | Unique Plate instance id. Must be unique per editor on the page. |
116
+ | `initialValue` | `WysiwygContent \| undefined` | yes | Document the editor is seeded with on mount. |
117
+ | `onChange` | `(value: WysiwygContent) => void` | yes | Called on every edit with the full document. |
118
+ | `plugins` | `UxfPlatePlugin[]` | yes | Build with `createAllPluginsWithUi` / `createPluginsWithUi`. |
119
+ | `className` | `string` | no | Class on the editor root wrapper. |
120
+ | `editableProps` | `TEditableProps<WysiwygContent>` | no | Passed to Plate's editable area (`placeholder`, `readOnly`, `autoFocus`, `spellCheck`, `className`, …). Defaults: `autoFocus: false`, `readOnly: false`, `spellCheck: false`, localized placeholder. |
121
+ | `ref` | `Ref<WysiwygEditorHandle>` | no | Imperative handle exposing `focus()`, which selects the end of the document and then focuses the editable area. |
122
+ | `customPluginsToolbarButtons` | `ReactNode` | no | Extra toolbar buttons appended to the built-in ones. |
123
+ | `toolbarLeftElement` | `ReactNode` | no | Node rendered at the toolbar's left edge. |
124
+ | `toolbarRightElement` | `ReactNode` | no | Node rendered at the toolbar's right edge. |
125
125
 
126
126
  ### Plugin builders
127
127
 
@@ -183,7 +183,7 @@ serializeToPlaintext(value); // keepIndentation defaults to true (joins blocks w
183
183
 
184
184
  ### Types
185
185
 
186
- `WysiwygEditorHandle` — the shape behind `editorRef`:
186
+ `WysiwygEditorHandle` — the shape behind `ref`:
187
187
 
188
188
  ```tsx
189
189
  import { WysiwygEditor } from "@uxf/wysiwyg";
@@ -193,7 +193,7 @@ import { useRef } from "react";
193
193
 
194
194
  const editorRef = useRef<WysiwygEditorHandle>(null);
195
195
 
196
- <WysiwygEditor editorRef={editorRef} id="body" initialValue={value} onChange={setValue} plugins={plugins} />;
196
+ <WysiwygEditor id="body" initialValue={value} onChange={setValue} plugins={plugins} ref={editorRef} />;
197
197
 
198
198
  editorRef.current?.focus(); // caret goes to the end of the document
199
199
  ```
@@ -9,7 +9,7 @@ const button_1 = require("./plugins/button");
9
9
  const create_video_plugin_1 = require("./plugins/embedded/video/create-video-plugin");
10
10
  const constants_1 = require("./plugins/heading/constants");
11
11
  const create_headings_plugin_1 = require("./plugins/heading/create-headings-plugin");
12
- const createHighlightPlugin_1 = require("./plugins/highlight/createHighlightPlugin");
12
+ const create_highlight_plugin_1 = require("./plugins/highlight/create-highlight-plugin");
13
13
  const create_image_plugin_1 = require("./plugins/image/create-image-plugin");
14
14
  const create_link_plugin_1 = require("./plugins/link/create-link-plugin");
15
15
  const create_list_plugin_1 = require("./plugins/list/create-list-plugin");
@@ -60,7 +60,7 @@ const createBoldPluginWithUi = () => ({
60
60
  });
61
61
  exports.createBoldPluginWithUi = createBoldPluginWithUi;
62
62
  const createHighlightPluginWithUi = (color = tw_colors_1.twColors.yellow["300"]) => ({
63
- plugin: (0, createHighlightPlugin_1.createHighlightPlugin)(color),
63
+ plugin: (0, create_highlight_plugin_1.createHighlightPlugin)(color),
64
64
  component: highlight_mark_1.HighlightMark,
65
65
  });
66
66
  exports.createHighlightPluginWithUi = createHighlightPluginWithUi;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/wysiwyg",
3
- "version": "12.7.0",
3
+ "version": "13.0.0",
4
4
  "description": "UXF Wysiwyg editor",
5
5
  "author": "Robin Dvorak <dvorak@uxf.cz>",
6
6
  "homepage": "https://gitlab.com/uxf-npm/wysiwyg",
@@ -18,12 +18,12 @@
18
18
  "@platejs/link": "53.3.5",
19
19
  "@platejs/list-classic": "53.0.0",
20
20
  "@platejs/media": "53.1.4",
21
- "@uxf/core": "12.7.0",
22
- "@uxf/core-react": "12.7.0",
23
- "@uxf/ui": "12.7.0",
21
+ "@uxf/core": "13.0.0",
22
+ "@uxf/core-react": "13.0.0",
23
+ "@uxf/ui": "13.0.0",
24
24
  "platejs": "53.3.15",
25
- "react": ">=18.2.0",
26
- "react-dom": ">=18.2.0"
25
+ "react": "^19.3.0",
26
+ "react-dom": "^19.3.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@platejs/basic-nodes": "53.0.0",
@@ -31,13 +31,13 @@
31
31
  "@platejs/link": "53.3.5",
32
32
  "@platejs/list-classic": "53.0.0",
33
33
  "@platejs/media": "53.1.4",
34
- "@types/react": "18.3.31",
35
- "@types/react-dom": "18.3.7",
36
- "@uxf/core": "12.7.0",
37
- "@uxf/core-react": "12.7.0",
38
- "@uxf/ui": "12.7.0",
34
+ "@types/react": "19.3.0",
35
+ "@types/react-dom": "19.3.0",
36
+ "@uxf/core": "13.0.0",
37
+ "@uxf/core-react": "13.0.0",
38
+ "@uxf/ui": "13.0.0",
39
39
  "platejs": "53.3.15",
40
- "react": "18.3.1",
41
- "react-dom": "18.3.1"
40
+ "react": "19.3.0",
41
+ "react-dom": "19.3.0"
42
42
  }
43
43
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const platejs_1 = require("platejs");
4
- const createHighlightPlugin_1 = require("./highlight/createHighlightPlugin");
4
+ const create_highlight_plugin_1 = require("./highlight/create-highlight-plugin");
5
5
  const create_bold_plugin_1 = require("./mark-bold/create-bold-plugin");
6
6
  const create_code_plugin_1 = require("./mark-code/create-code-plugin");
7
7
  const create_italic_plugin_1 = require("./mark-italic/create-italic-plugin");
@@ -12,7 +12,7 @@ const editor = (0, platejs_1.createSlateEditor)({
12
12
  (0, create_italic_plugin_1.createItalicPlugin)(),
13
13
  (0, create_underline_plugin_1.createUnderlinePlugin)(),
14
14
  (0, create_code_plugin_1.createCodePlugin)(),
15
- (0, createHighlightPlugin_1.createHighlightPlugin)("red"),
15
+ (0, create_highlight_plugin_1.createHighlightPlugin)("red"),
16
16
  ],
17
17
  });
18
18
  describe("marks", () => {
@@ -1,6 +1,6 @@
1
1
  import { Noop } from "@uxf/core/types";
2
2
  import { PlateContentProps } from "platejs/react";
3
- import { FC, ForwardedRef, ReactNode } from "react";
3
+ import { FC, ReactNode, RefAttributes } from "react";
4
4
  import { UxfPlatePlugin, WysiwygContent } from "./types";
5
5
  export interface WysiwygEditorHandle {
6
6
  focus: Noop;
@@ -9,7 +9,6 @@ export interface WysiwygEditorProps {
9
9
  className?: string;
10
10
  customPluginsToolbarButtons?: ReactNode;
11
11
  editableProps?: PlateContentProps;
12
- editorRef?: ForwardedRef<WysiwygEditorHandle>;
13
12
  id: string;
14
13
  initialValue: WysiwygContent | undefined;
15
14
  onChange: (value: WysiwygContent) => void;
@@ -17,4 +16,4 @@ export interface WysiwygEditorProps {
17
16
  toolbarLeftElement?: ReactNode;
18
17
  toolbarRightElement?: ReactNode;
19
18
  }
20
- export declare const WysiwygEditor: FC<WysiwygEditorProps>;
19
+ export declare const WysiwygEditor: FC<WysiwygEditorProps & RefAttributes<WysiwygEditorHandle>>;
package/wysiwyg-editor.js CHANGED
@@ -49,9 +49,9 @@ const CLASS_NAME = "uxf-wysiwyg";
49
49
  * Component that accesses the editor from Slate context and exposes focus method via ref
50
50
  * Must be rendered inside Plate component
51
51
  */
52
- const EditorRefHandler = (0, react_2.forwardRef)((props, ref) => {
52
+ function EditorRefHandler(props) {
53
53
  const editor = (0, hooks_1.useUxfEditorRef)();
54
- (0, react_2.useImperativeHandle)(ref, () => ({
54
+ (0, react_2.useImperativeHandle)(props.ref, () => ({
55
55
  focus: () => {
56
56
  // Select the end of the document first
57
57
  editor.tf.select(editor.api.end([]));
@@ -60,7 +60,7 @@ const EditorRefHandler = (0, react_2.forwardRef)((props, ref) => {
60
60
  },
61
61
  }));
62
62
  return null;
63
- });
63
+ }
64
64
  EditorRefHandler.displayName = "EditorRefHandler";
65
65
  const Editor = (props) => {
66
66
  var _a, _b;
@@ -84,7 +84,7 @@ const Editor = (props) => {
84
84
  spellCheck: false,
85
85
  ...props.editableProps,
86
86
  className: `${CLASS_NAME}__editable ${(_b = (_a = props.editableProps) === null || _a === void 0 ? void 0 : _a.className) !== null && _b !== void 0 ? _b : ""}` }),
87
- props.editorRef && react_2.default.createElement(EditorRefHandler, { ref: props.editorRef }))));
87
+ props.ref && react_2.default.createElement(EditorRefHandler, { ref: props.ref }))));
88
88
  };
89
89
  const WysiwygEditor = (props) => {
90
90
  var _a, _b;
@@ -94,6 +94,6 @@ const WysiwygEditor = (props) => {
94
94
  react_2.default.createElement(loader_1.Loader, { className: `${CLASS_NAME}__loader` })));
95
95
  }
96
96
  return (react_2.default.createElement("div", { className: `${CLASS_NAME} ${(_b = props.className) !== null && _b !== void 0 ? _b : ""}` },
97
- react_2.default.createElement(Editor, { customPluginsToolbarButtons: props.customPluginsToolbarButtons, editableProps: props.editableProps, editorRef: props.editorRef, id: props.id, initialValue: props.initialValue, onChange: props.onChange, plugins: props.plugins, toolbarLeftElement: props.toolbarLeftElement, toolbarRightElement: props.toolbarRightElement })));
97
+ react_2.default.createElement(Editor, { customPluginsToolbarButtons: props.customPluginsToolbarButtons, editableProps: props.editableProps, id: props.id, initialValue: props.initialValue, onChange: props.onChange, plugins: props.plugins, ref: props.ref, toolbarLeftElement: props.toolbarLeftElement, toolbarRightElement: props.toolbarRightElement })));
98
98
  };
99
99
  exports.WysiwygEditor = WysiwygEditor;
@@ -65,7 +65,7 @@ async function settle() {
65
65
  }
66
66
  async function renderEditor(editorRef) {
67
67
  const result = (0, react_1.render)(react_2.default.createElement(context_1.UiContextProvider, { value: UI_CONTEXT },
68
- react_2.default.createElement(wysiwyg_editor_1.WysiwygEditor, { editorRef: editorRef, id: "test-editor", initialValue: INITIAL_VALUE, onChange: () => undefined, plugins: (0, create_plugins_with_ui_1.createPluginsWithUi)([(0, create_all_plugins_with_ui_1.createBoldPluginWithUi)()]) })));
68
+ react_2.default.createElement(wysiwyg_editor_1.WysiwygEditor, { id: "test-editor", initialValue: INITIAL_VALUE, onChange: () => undefined, plugins: (0, create_plugins_with_ui_1.createPluginsWithUi)([(0, create_all_plugins_with_ui_1.createBoldPluginWithUi)()]), ref: editorRef })));
69
69
  await settle();
70
70
  return result;
71
71
  }
@@ -130,11 +130,11 @@ afterEach(() => {
130
130
  expect(actWarnings).toEqual([]);
131
131
  });
132
132
  describe("WysiwygEditor", () => {
133
- it("renders without an editorRef", async () => {
133
+ it("renders without a ref", async () => {
134
134
  const { container } = await renderEditor();
135
135
  expect(container.querySelector(".uxf-wysiwyg__editable")).not.toBeNull();
136
136
  });
137
- it("exposes focus() through editorRef", async () => {
137
+ it("exposes focus() through its ref", async () => {
138
138
  var _a;
139
139
  const editorRef = (0, react_2.createRef)();
140
140
  await renderEditor(editorRef);