@openeditor/native 0.0.10 → 0.0.12
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/dist/index.d.ts +8 -2
- package/dist/index.js +42 -7
- package/dist/toolbar.d.ts +3 -0
- package/dist/toolbar.js +9 -0
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ export type OpenEditorNativeProps = {
|
|
|
10
10
|
theme?: Partial<OpenEditorNativeTheme>;
|
|
11
11
|
toolbarPlacement?: NativeRichTextEditorToolbarPlacement;
|
|
12
12
|
onChange?: (document: OpenEditorDocument) => void;
|
|
13
|
+
onOpenPage?: (page: {
|
|
14
|
+
pageId: string;
|
|
15
|
+
title: string;
|
|
16
|
+
icon?: string | null;
|
|
17
|
+
href?: string | null;
|
|
18
|
+
}) => void;
|
|
13
19
|
};
|
|
14
20
|
export type OpenEditorNativeViewerProps = Omit<OpenEditorNativeProps, "editable" | "showToolbar" | "onChange"> & {
|
|
15
21
|
showToolbar?: false;
|
|
@@ -61,8 +67,8 @@ export type OpenEditorNativeTheme = {
|
|
|
61
67
|
toolbar?: OpenEditorNativeToolbarTheme;
|
|
62
68
|
};
|
|
63
69
|
export declare const OpenEditorNativeToolbar: ({ actions, onActionPress, theme, }: OpenEditorNativeToolbarProps) => import("react").JSX.Element;
|
|
64
|
-
export declare const OpenEditorNative: ({ document, editable, placeholder, showToolbar, theme, toolbarPlacement, onChange, }: OpenEditorNativeProps) => import("react").JSX.Element;
|
|
65
|
-
export declare const OpenEditorNativeViewer: ({ document, theme, renderers, }: OpenEditorNativeViewerProps) => import("react").JSX.Element;
|
|
70
|
+
export declare const OpenEditorNative: ({ document, editable, placeholder, showToolbar, theme, toolbarPlacement, onChange, onOpenPage, }: OpenEditorNativeProps) => import("react").JSX.Element;
|
|
71
|
+
export declare const OpenEditorNativeViewer: ({ document, theme, renderers, onOpenPage, }: OpenEditorNativeViewerProps) => import("react").JSX.Element;
|
|
66
72
|
export { createNativeEditorDocument, fromNativeEditorDocument, sanitizeNativeEditorDocument, toNativeEditorDocument, } from "./document.js";
|
|
67
73
|
export { createOpenEditorNativeToolbarItems, defaultDocumentForToolbarAction, nativeToolbarParityCoverage, openEditorNativeToolbarActionKeys, openEditorNativeToolbarItems, } from "./toolbar.js";
|
|
68
74
|
export type { OpenEditorNativeToolbarActionKey } from "./toolbar.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createDocument, findBlockSpecForNode, moveTopLevelBlock, textBlock, } from "@openeditor/core";
|
|
3
3
|
import { useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Image as NativeImage, Keyboard, Modal, Platform, Pressable, StyleSheet, Text, TextInput, View } from "react-native";
|
|
@@ -58,6 +58,34 @@ const openEditorNativeSchema = {
|
|
|
58
58
|
htmlTag: "li",
|
|
59
59
|
attrs: { checked: { default: false } },
|
|
60
60
|
},
|
|
61
|
+
{ name: "toggleList", content: "toggleListItem+", group: "block", role: "list", htmlTag: "ul" },
|
|
62
|
+
{
|
|
63
|
+
name: "toggleListItem",
|
|
64
|
+
content: "paragraph block*",
|
|
65
|
+
role: "listItem",
|
|
66
|
+
htmlTag: "li",
|
|
67
|
+
attrs: { open: { default: true } },
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "callout",
|
|
71
|
+
content: "block+",
|
|
72
|
+
group: "block",
|
|
73
|
+
role: "block",
|
|
74
|
+
htmlTag: "aside",
|
|
75
|
+
attrs: { tone: { default: "info" } },
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "page",
|
|
79
|
+
content: "inline*",
|
|
80
|
+
group: "block",
|
|
81
|
+
role: "textBlock",
|
|
82
|
+
htmlTag: "p",
|
|
83
|
+
attrs: {
|
|
84
|
+
pageId: { default: null },
|
|
85
|
+
icon: { default: "📄" },
|
|
86
|
+
href: { default: null },
|
|
87
|
+
},
|
|
88
|
+
},
|
|
61
89
|
{ name: "codeBlock", content: "text*", group: "block", role: "textBlock", htmlTag: "pre" },
|
|
62
90
|
{ name: "horizontalRule", content: "", group: "block", role: "block", htmlTag: "hr", isVoid: true },
|
|
63
91
|
{
|
|
@@ -291,11 +319,11 @@ const nativeSeedDocument = createDocument([
|
|
|
291
319
|
{ type: "horizontalRule" },
|
|
292
320
|
{ type: "image", attrs: { src: "https://placehold.co/960x420/png", alt: "Placeholder" } },
|
|
293
321
|
]);
|
|
294
|
-
const renderNativeViewerNode = (node, key, theme, renderers) => {
|
|
322
|
+
const renderNativeViewerNode = (node, key, theme, renderers, onOpenPage) => {
|
|
295
323
|
if (node.type === "text") {
|
|
296
324
|
return _jsx(Text, { style: { color: theme.text }, children: node.text ?? "" }, key);
|
|
297
325
|
}
|
|
298
|
-
const children = node.content?.map((child, index) => renderNativeViewerNode(child, `${key}-${index}`, theme, renderers)) ?? null;
|
|
326
|
+
const children = node.content?.map((child, index) => renderNativeViewerNode(child, `${key}-${index}`, theme, renderers, onOpenPage)) ?? null;
|
|
299
327
|
const blockKey = findBlockSpecForNode(defaultBlockRegistry, node)?.name ?? node.type;
|
|
300
328
|
const customRenderer = renderers?.[blockKey];
|
|
301
329
|
if (customRenderer) {
|
|
@@ -325,6 +353,13 @@ const renderNativeViewerNode = (node, key, theme, renderers) => {
|
|
|
325
353
|
return _jsx(View, { style: { flexDirection: "row", gap: 12, marginBottom: 12 }, children: children }, key);
|
|
326
354
|
case "table":
|
|
327
355
|
return _jsx(View, { style: { borderColor: theme.border, borderRadius: 8, borderWidth: 1, marginBottom: 12, overflow: "hidden" }, children: children }, key);
|
|
356
|
+
case "page": {
|
|
357
|
+
const pageId = typeof node.attrs?.pageId === "string" ? node.attrs.pageId : "";
|
|
358
|
+
const title = node.content?.map((child) => child.text ?? "").join("") || "Untitled";
|
|
359
|
+
const icon = typeof node.attrs?.icon === "string" ? node.attrs.icon : "📄";
|
|
360
|
+
const content = _jsxs(_Fragment, { children: [_jsx(Text, { style: { fontSize: 18 }, children: icon }), _jsx(Text, { style: { color: theme.text, flex: 1, fontWeight: "600", textDecorationLine: "underline" }, children: title }), _jsx(Text, { style: { color: theme.muted }, children: "\u2192" })] });
|
|
361
|
+
return onOpenPage && pageId ? (_jsx(Pressable, { accessibilityRole: "button", onPress: () => onOpenPage({ pageId, title, icon, href: typeof node.attrs?.href === "string" ? node.attrs.href : null }), style: { alignItems: "center", borderRadius: 8, flexDirection: "row", gap: 8, marginBottom: 8, padding: 8 }, children: content }, key)) : _jsx(View, { style: { alignItems: "center", flexDirection: "row", gap: 8, marginBottom: 8, padding: 8 }, children: content }, key);
|
|
362
|
+
}
|
|
328
363
|
default:
|
|
329
364
|
if (node.type === "column") {
|
|
330
365
|
return _jsx(View, { style: { flex: 1 }, children: children }, key);
|
|
@@ -361,7 +396,7 @@ export const OpenEditorNativeToolbar = ({ actions = [
|
|
|
361
396
|
onActionPress?.(action.key);
|
|
362
397
|
}, style: [styles.toolbarButton, { backgroundColor: resolvedTheme.accent, borderColor: resolvedTheme.borderStrong }], children: _jsx(Text, { style: [styles.toolbarButtonText, { color: resolvedTheme.accentText }], children: action.label }) }, action.key))) }));
|
|
363
398
|
};
|
|
364
|
-
export const OpenEditorNative = ({ document = nativeSeedDocument, editable = true, placeholder = "Start writing...", showToolbar = true, theme, toolbarPlacement = "keyboard", onChange, }) => {
|
|
399
|
+
export const OpenEditorNative = ({ document = nativeSeedDocument, editable = true, placeholder = "Start writing...", showToolbar = true, theme, toolbarPlacement = "keyboard", onChange, onOpenPage, }) => {
|
|
365
400
|
const editorRef = useRef(null);
|
|
366
401
|
const [currentDocument, setCurrentDocument] = useState(() => normalizeForNativeEditor(document));
|
|
367
402
|
const [selection, setSelection] = useState();
|
|
@@ -501,11 +536,11 @@ export const OpenEditorNative = ({ document = nativeSeedDocument, editable = tru
|
|
|
501
536
|
}, onRequestImage: (request) => {
|
|
502
537
|
setImageUrl("https://placehold.co/960x420/png");
|
|
503
538
|
setImageRequest(request);
|
|
504
|
-
}, onSelectionChange: setSelection, onContentChangeJSON: (json) => {
|
|
539
|
+
}, onOpenPage: onOpenPage, onSelectionChange: setSelection, onContentChangeJSON: (json) => {
|
|
505
540
|
syncDocument(contentFromNativeJson(json), false);
|
|
506
541
|
}, style: styles.nativeEditor }), _jsx(UrlDialog, { title: "Link", value: linkUrl, visible: linkRequest !== null, placeholder: "https://", confirmLabel: linkUrl.trim() ? "Apply" : "Remove", onChangeText: setLinkUrl, onCancel: () => setLinkRequest(null), onSubmit: submitLinkDialog, theme: resolvedTheme }), _jsx(UrlDialog, { title: "Image", value: imageUrl, visible: imageRequest !== null, placeholder: "https://", confirmLabel: "Insert", onChangeText: setImageUrl, onCancel: () => setImageRequest(null), onSubmit: submitImageDialog, theme: resolvedTheme })] }));
|
|
507
542
|
};
|
|
508
|
-
export const OpenEditorNativeViewer = ({ document = nativeSeedDocument, theme, renderers, }) => {
|
|
543
|
+
export const OpenEditorNativeViewer = ({ document = nativeSeedDocument, theme, renderers, onOpenPage, }) => {
|
|
509
544
|
const resolvedTheme = {
|
|
510
545
|
...defaultNativeTheme,
|
|
511
546
|
...theme,
|
|
@@ -515,7 +550,7 @@ export const OpenEditorNativeViewer = ({ document = nativeSeedDocument, theme, r
|
|
|
515
550
|
},
|
|
516
551
|
};
|
|
517
552
|
const normalizedDocument = normalizeForNativeEditor(document);
|
|
518
|
-
return (_jsx(View, { style: [styles.viewer, { backgroundColor: resolvedTheme.surface, borderColor: resolvedTheme.border }], children: normalizedDocument.content.map((node, index) => renderNativeViewerNode(node, `native-viewer-${index}`, resolvedTheme, renderers)) }));
|
|
553
|
+
return (_jsx(View, { style: [styles.viewer, { backgroundColor: resolvedTheme.surface, borderColor: resolvedTheme.border }], children: normalizedDocument.content.map((node, index) => renderNativeViewerNode(node, `native-viewer-${index}`, resolvedTheme, renderers, onOpenPage)) }));
|
|
519
554
|
};
|
|
520
555
|
const CommandButton = ({ label, active = false, primary = false, theme, onPress, }) => (_jsx(Pressable, { accessibilityRole: "button", accessibilityState: { selected: active }, onPress: onPress, style: [
|
|
521
556
|
styles.commandButton,
|
package/dist/toolbar.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export declare const openEditorNativeToolbarActionKeys: {
|
|
|
6
6
|
readonly orderedList: "orderedList";
|
|
7
7
|
readonly columns: "columns";
|
|
8
8
|
readonly table: "table";
|
|
9
|
+
readonly toggleList: "toggleList";
|
|
10
|
+
readonly callout: "callout";
|
|
11
|
+
readonly page: "page";
|
|
9
12
|
readonly moveBlockUp: "openeditor:block:moveUp";
|
|
10
13
|
readonly moveBlockDown: "openeditor:block:moveDown";
|
|
11
14
|
readonly undo: "openeditor:history:undo";
|
package/dist/toolbar.js
CHANGED
|
@@ -14,6 +14,9 @@ export const openEditorNativeToolbarActionKeys = {
|
|
|
14
14
|
orderedList: "orderedList",
|
|
15
15
|
columns: "columns",
|
|
16
16
|
table: "table",
|
|
17
|
+
toggleList: "toggleList",
|
|
18
|
+
callout: "callout",
|
|
19
|
+
page: "page",
|
|
17
20
|
moveBlockUp: "openeditor:block:moveUp",
|
|
18
21
|
moveBlockDown: "openeditor:block:moveDown",
|
|
19
22
|
undo: "openeditor:history:undo",
|
|
@@ -77,6 +80,9 @@ export const createOpenEditorNativeToolbarItems = ({ canUndo = true, canRedo = t
|
|
|
77
80
|
{ type: "node", nodeType: "horizontalRule", label: "Divider", icon: defaultIcon("horizontalRule") },
|
|
78
81
|
{ type: "action", key: openEditorNativeToolbarActionKeys.columns, label: "Columns", icon: glyphIcon("Cols") },
|
|
79
82
|
{ type: "action", key: openEditorNativeToolbarActionKeys.table, label: "Table", icon: glyphIcon("Tbl") },
|
|
83
|
+
{ type: "action", key: openEditorNativeToolbarActionKeys.toggleList, label: "Toggle List", icon: glyphIcon("Tgl") },
|
|
84
|
+
{ type: "action", key: openEditorNativeToolbarActionKeys.callout, label: "Callout", icon: glyphIcon("!") },
|
|
85
|
+
{ type: "action", key: openEditorNativeToolbarActionKeys.page, label: "Page", icon: glyphIcon("Pg") },
|
|
80
86
|
{ type: "command", command: "insertTableRowAfter", label: "Add Row", icon: glyphIcon("+R") },
|
|
81
87
|
{ type: "command", command: "insertTableColumnAfter", label: "Add Column", icon: glyphIcon("+C") },
|
|
82
88
|
{ type: "command", command: "deleteTableRow", label: "Delete Row", icon: glyphIcon("-R") },
|
|
@@ -162,6 +168,9 @@ export const nativeToolbarParityCoverage = () => {
|
|
|
162
168
|
["divider", "horizontalRule"],
|
|
163
169
|
["image", "image"],
|
|
164
170
|
["table", openEditorNativeToolbarActionKeys.table],
|
|
171
|
+
["toggleList", openEditorNativeToolbarActionKeys.toggleList],
|
|
172
|
+
["callout", openEditorNativeToolbarActionKeys.callout],
|
|
173
|
+
["page", openEditorNativeToolbarActionKeys.page],
|
|
165
174
|
]);
|
|
166
175
|
const markControls = new Map([
|
|
167
176
|
["bold", "bold"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openeditor/native",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"repository": {
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@expo/vector-icons": "15.0.3",
|
|
30
|
-
"@openeditor/core": "0.0.
|
|
31
|
-
"@openeditor/exporters": "0.0.
|
|
32
|
-
"@openeditor/extensions": "0.0.
|
|
30
|
+
"@openeditor/core": "0.0.12",
|
|
31
|
+
"@openeditor/exporters": "0.0.12",
|
|
32
|
+
"@openeditor/extensions": "0.0.12",
|
|
33
33
|
"react": "19.2.3",
|
|
34
34
|
"react-native": "0.85.3"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@openeditor/react-native-prose-editor": "0.0.
|
|
37
|
+
"@openeditor/react-native-prose-editor": "0.0.12",
|
|
38
38
|
"react-native-keyboard-controller": ">=1.21",
|
|
39
39
|
"react": ">=19",
|
|
40
40
|
"react-native": ">=0.85"
|