@openeditor/native 0.0.12 → 0.0.14
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 +2 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +73 -12
- package/dist/toolbar.d.ts +1 -0
- package/dist/toolbar.js +8 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Component-first React Native SDK for OpenEditor.
|
|
4
4
|
|
|
5
|
+
Pass `attachmentRuntime` to use the system picker and host storage lifecycle. The native toolbar exposes “Upload file,” native surfaces render attachment cards, and the viewer delegates opening/sharing to the runtime.
|
|
6
|
+
|
|
5
7
|
## Public surface
|
|
6
8
|
|
|
7
9
|
- `OpenEditorNative` as the primary editing surface
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type OpenEditorDocument, type ProseMirrorNode } from "@openeditor/core";
|
|
1
|
+
import { type OpenEditorDocument, type OpenEditorAttachmentRuntime, type ProseMirrorNode } from "@openeditor/core";
|
|
2
2
|
import { type ReactNode } from "react";
|
|
3
3
|
import type { NativeRichTextEditorToolbarPlacement } from "@openeditor/react-native-prose-editor";
|
|
4
4
|
export { normalizeNativeThemeColor } from "./theme.js";
|
|
@@ -16,6 +16,7 @@ export type OpenEditorNativeProps = {
|
|
|
16
16
|
icon?: string | null;
|
|
17
17
|
href?: string | null;
|
|
18
18
|
}) => void;
|
|
19
|
+
attachmentRuntime?: OpenEditorAttachmentRuntime<any>;
|
|
19
20
|
};
|
|
20
21
|
export type OpenEditorNativeViewerProps = Omit<OpenEditorNativeProps, "editable" | "showToolbar" | "onChange"> & {
|
|
21
22
|
showToolbar?: false;
|
|
@@ -67,8 +68,8 @@ export type OpenEditorNativeTheme = {
|
|
|
67
68
|
toolbar?: OpenEditorNativeToolbarTheme;
|
|
68
69
|
};
|
|
69
70
|
export declare const OpenEditorNativeToolbar: ({ actions, onActionPress, theme, }: OpenEditorNativeToolbarProps) => 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;
|
|
71
|
+
export declare const OpenEditorNative: ({ document, editable, placeholder, showToolbar, theme, toolbarPlacement, onChange, onOpenPage, attachmentRuntime, }: OpenEditorNativeProps) => import("react").JSX.Element;
|
|
72
|
+
export declare const OpenEditorNativeViewer: ({ document, theme, renderers, onOpenPage, attachmentRuntime, }: OpenEditorNativeViewerProps) => import("react").JSX.Element;
|
|
72
73
|
export { createNativeEditorDocument, fromNativeEditorDocument, sanitizeNativeEditorDocument, toNativeEditorDocument, } from "./document.js";
|
|
73
74
|
export { createOpenEditorNativeToolbarItems, defaultDocumentForToolbarAction, nativeToolbarParityCoverage, openEditorNativeToolbarActionKeys, openEditorNativeToolbarItems, } from "./toolbar.js";
|
|
74
75
|
export type { OpenEditorNativeToolbarActionKey } from "./toolbar.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
2
|
-
import { createDocument, findBlockSpecForNode, moveTopLevelBlock, textBlock, } from "@openeditor/core";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { DEFAULT_CALLOUT_EMOJI, DEFAULT_PAGE_EMOJI, createDocument, findBlockSpecForNode, moveTopLevelBlock, normalizeEmoji, 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";
|
|
5
5
|
import { fromNativeEditorDocument, sanitizeNativeEditorDocument, toNativeEditorDocument, } from "./document.js";
|
|
@@ -72,7 +72,7 @@ const openEditorNativeSchema = {
|
|
|
72
72
|
group: "block",
|
|
73
73
|
role: "block",
|
|
74
74
|
htmlTag: "aside",
|
|
75
|
-
attrs: {
|
|
75
|
+
attrs: { emoji: { default: DEFAULT_CALLOUT_EMOJI } },
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
name: "page",
|
|
@@ -82,10 +82,25 @@ const openEditorNativeSchema = {
|
|
|
82
82
|
htmlTag: "p",
|
|
83
83
|
attrs: {
|
|
84
84
|
pageId: { default: null },
|
|
85
|
-
icon: { default:
|
|
85
|
+
icon: { default: DEFAULT_PAGE_EMOJI },
|
|
86
86
|
href: { default: null },
|
|
87
87
|
},
|
|
88
88
|
},
|
|
89
|
+
{
|
|
90
|
+
name: "attachment",
|
|
91
|
+
content: "",
|
|
92
|
+
group: "block",
|
|
93
|
+
role: "block",
|
|
94
|
+
htmlTag: "div",
|
|
95
|
+
isVoid: true,
|
|
96
|
+
attrs: {
|
|
97
|
+
attachmentId: { default: null },
|
|
98
|
+
name: { default: "" },
|
|
99
|
+
mimeType: { default: null },
|
|
100
|
+
size: { default: null },
|
|
101
|
+
url: { default: null },
|
|
102
|
+
},
|
|
103
|
+
},
|
|
89
104
|
{ name: "codeBlock", content: "text*", group: "block", role: "textBlock", htmlTag: "pre" },
|
|
90
105
|
{ name: "horizontalRule", content: "", group: "block", role: "block", htmlTag: "hr", isVoid: true },
|
|
91
106
|
{
|
|
@@ -319,11 +334,11 @@ const nativeSeedDocument = createDocument([
|
|
|
319
334
|
{ type: "horizontalRule" },
|
|
320
335
|
{ type: "image", attrs: { src: "https://placehold.co/960x420/png", alt: "Placeholder" } },
|
|
321
336
|
]);
|
|
322
|
-
const renderNativeViewerNode = (node, key, theme, renderers, onOpenPage) => {
|
|
337
|
+
const renderNativeViewerNode = (node, key, theme, renderers, onOpenPage, attachmentRuntime) => {
|
|
323
338
|
if (node.type === "text") {
|
|
324
339
|
return _jsx(Text, { style: { color: theme.text }, children: node.text ?? "" }, key);
|
|
325
340
|
}
|
|
326
|
-
const children = node.content?.map((child, index) => renderNativeViewerNode(child, `${key}-${index}`, theme, renderers, onOpenPage)) ?? null;
|
|
341
|
+
const children = node.content?.map((child, index) => renderNativeViewerNode(child, `${key}-${index}`, theme, renderers, onOpenPage, attachmentRuntime)) ?? null;
|
|
327
342
|
const blockKey = findBlockSpecForNode(defaultBlockRegistry, node)?.name ?? node.type;
|
|
328
343
|
const customRenderer = renderers?.[blockKey];
|
|
329
344
|
if (customRenderer) {
|
|
@@ -345,6 +360,10 @@ const renderNativeViewerNode = (node, key, theme, renderers, onOpenPage) => {
|
|
|
345
360
|
return _jsx(View, { style: { borderLeftColor: theme.accent, borderLeftWidth: 3, marginBottom: 12, paddingLeft: 12 }, children: children }, key);
|
|
346
361
|
case "codeBlock":
|
|
347
362
|
return _jsx(View, { style: { backgroundColor: theme.codeBackground, borderRadius: 8, marginBottom: 12, padding: 12 }, children: _jsx(Text, { style: { color: theme.codeText }, children: node.content?.map((child) => child.text ?? "").join("") }) }, key);
|
|
363
|
+
case "callout": {
|
|
364
|
+
const emoji = normalizeEmoji(node.attrs?.emoji, DEFAULT_CALLOUT_EMOJI);
|
|
365
|
+
return _jsxs(View, { style: { backgroundColor: theme.codeBackground, borderRadius: 10, flexDirection: "row", gap: 10, marginBottom: 12, padding: 14 }, children: [_jsx(Text, { style: { fontSize: 20 }, children: emoji }), _jsx(View, { style: { flex: 1 }, children: children })] }, key);
|
|
366
|
+
}
|
|
348
367
|
case "divider":
|
|
349
368
|
return _jsx(View, { style: { backgroundColor: theme.border, height: 1, marginVertical: 16 } }, key);
|
|
350
369
|
case "image":
|
|
@@ -356,10 +375,21 @@ const renderNativeViewerNode = (node, key, theme, renderers, onOpenPage) => {
|
|
|
356
375
|
case "page": {
|
|
357
376
|
const pageId = typeof node.attrs?.pageId === "string" ? node.attrs.pageId : "";
|
|
358
377
|
const title = node.content?.map((child) => child.text ?? "").join("") || "Untitled";
|
|
359
|
-
const icon =
|
|
378
|
+
const icon = normalizeEmoji(node.attrs?.icon, DEFAULT_PAGE_EMOJI);
|
|
360
379
|
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
380
|
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
381
|
}
|
|
382
|
+
case "attachment": {
|
|
383
|
+
const snapshot = {
|
|
384
|
+
attachmentId: typeof node.attrs?.attachmentId === "string" ? node.attrs.attachmentId : null,
|
|
385
|
+
name: typeof node.attrs?.name === "string" ? node.attrs.name : "Attachment",
|
|
386
|
+
mimeType: typeof node.attrs?.mimeType === "string" ? node.attrs.mimeType : null,
|
|
387
|
+
size: typeof node.attrs?.size === "number" ? node.attrs.size : null,
|
|
388
|
+
url: typeof node.attrs?.url === "string" ? node.attrs.url : null,
|
|
389
|
+
};
|
|
390
|
+
const content = _jsxs(_Fragment, { children: [_jsx(Text, { style: { fontSize: 22 }, children: "\uD83D\uDCCE" }), _jsxs(View, { style: { flex: 1 }, children: [_jsx(Text, { numberOfLines: 1, style: { color: theme.text, fontWeight: "600" }, children: snapshot.name }), _jsx(Text, { style: { color: theme.muted, fontSize: 12 }, children: snapshot.mimeType ?? "File" })] }), _jsx(Text, { style: { color: theme.muted }, children: "Open" })] });
|
|
391
|
+
return attachmentRuntime?.openAttachment ? _jsx(Pressable, { accessibilityLabel: `Open ${snapshot.name}`, accessibilityRole: "button", onPress: () => void attachmentRuntime.openAttachment?.(snapshot), style: { alignItems: "center", borderColor: theme.border, borderRadius: 10, borderWidth: 1, flexDirection: "row", gap: 10, marginBottom: 8, minHeight: 64, padding: 10 }, children: content }, key) : _jsx(View, { style: { alignItems: "center", borderColor: theme.border, borderRadius: 10, borderWidth: 1, flexDirection: "row", gap: 10, marginBottom: 8, minHeight: 64, padding: 10 }, children: content }, key);
|
|
392
|
+
}
|
|
363
393
|
default:
|
|
364
394
|
if (node.type === "column") {
|
|
365
395
|
return _jsx(View, { style: { flex: 1 }, children: children }, key);
|
|
@@ -396,7 +426,7 @@ export const OpenEditorNativeToolbar = ({ actions = [
|
|
|
396
426
|
onActionPress?.(action.key);
|
|
397
427
|
}, style: [styles.toolbarButton, { backgroundColor: resolvedTheme.accent, borderColor: resolvedTheme.borderStrong }], children: _jsx(Text, { style: [styles.toolbarButtonText, { color: resolvedTheme.accentText }], children: action.label }) }, action.key))) }));
|
|
398
428
|
};
|
|
399
|
-
export const OpenEditorNative = ({ document = nativeSeedDocument, editable = true, placeholder = "Start writing...", showToolbar = true, theme, toolbarPlacement = "keyboard", onChange, onOpenPage, }) => {
|
|
429
|
+
export const OpenEditorNative = ({ document = nativeSeedDocument, editable = true, placeholder = "Start writing...", showToolbar = true, theme, toolbarPlacement = "keyboard", onChange, onOpenPage, attachmentRuntime, }) => {
|
|
400
430
|
const editorRef = useRef(null);
|
|
401
431
|
const [currentDocument, setCurrentDocument] = useState(() => normalizeForNativeEditor(document));
|
|
402
432
|
const [selection, setSelection] = useState();
|
|
@@ -404,6 +434,8 @@ export const OpenEditorNative = ({ document = nativeSeedDocument, editable = tru
|
|
|
404
434
|
const [linkUrl, setLinkUrl] = useState("https://");
|
|
405
435
|
const [imageRequest, setImageRequest] = useState(null);
|
|
406
436
|
const [imageUrl, setImageUrl] = useState("https://placehold.co/960x420/png");
|
|
437
|
+
const [attachmentUpload, setAttachmentUpload] = useState(null);
|
|
438
|
+
const attachmentAbortRef = useRef(null);
|
|
407
439
|
const [history, setHistory] = useState({
|
|
408
440
|
undoStack: [],
|
|
409
441
|
redoStack: [],
|
|
@@ -445,6 +477,31 @@ export const OpenEditorNative = ({ document = nativeSeedDocument, editable = tru
|
|
|
445
477
|
}
|
|
446
478
|
syncDocument(moveTopLevelBlock(nativeDocument, selectedIndex, nextIndex), true);
|
|
447
479
|
};
|
|
480
|
+
const uploadAttachment = async () => {
|
|
481
|
+
if (!attachmentRuntime?.selectAttachment || !attachmentRuntime.uploadAttachment)
|
|
482
|
+
return;
|
|
483
|
+
attachmentAbortRef.current?.abort();
|
|
484
|
+
const controller = new AbortController();
|
|
485
|
+
attachmentAbortRef.current = controller;
|
|
486
|
+
try {
|
|
487
|
+
const input = await attachmentRuntime.selectAttachment({ signal: controller.signal });
|
|
488
|
+
if (!input || controller.signal.aborted)
|
|
489
|
+
return;
|
|
490
|
+
setAttachmentUpload({ input, progress: 0, error: null });
|
|
491
|
+
const validation = await attachmentRuntime.validateAttachment?.(input);
|
|
492
|
+
if (validation && !validation.accepted)
|
|
493
|
+
throw new Error(validation.message);
|
|
494
|
+
const snapshot = await attachmentRuntime.uploadAttachment(input, { signal: controller.signal, onProgress: (progress) => setAttachmentUpload((current) => current ? { ...current, progress } : current) });
|
|
495
|
+
if (controller.signal.aborted)
|
|
496
|
+
return;
|
|
497
|
+
editorRef.current?.insertContentJson({ type: "doc", content: [{ type: "attachment", attrs: snapshot }] });
|
|
498
|
+
setAttachmentUpload(null);
|
|
499
|
+
}
|
|
500
|
+
catch (cause) {
|
|
501
|
+
if (!controller.signal.aborted)
|
|
502
|
+
setAttachmentUpload((current) => current ? { ...current, error: cause instanceof Error ? cause.message : "Upload failed." } : current);
|
|
503
|
+
}
|
|
504
|
+
};
|
|
448
505
|
const handleToolbarAction = (key) => {
|
|
449
506
|
if (key === openEditorNativeToolbarActionKeys.dismissKeyboard) {
|
|
450
507
|
dismissKeyboard();
|
|
@@ -458,6 +515,10 @@ export const OpenEditorNative = ({ document = nativeSeedDocument, editable = tru
|
|
|
458
515
|
moveSelectedBlock(1);
|
|
459
516
|
return;
|
|
460
517
|
}
|
|
518
|
+
if (key === openEditorNativeToolbarActionKeys.attachment) {
|
|
519
|
+
void uploadAttachment();
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
461
522
|
if (key === openEditorNativeToolbarActionKeys.undo) {
|
|
462
523
|
const previous = history.undoStack[history.undoStack.length - 1];
|
|
463
524
|
if (!previous) {
|
|
@@ -536,11 +597,11 @@ export const OpenEditorNative = ({ document = nativeSeedDocument, editable = tru
|
|
|
536
597
|
}, onRequestImage: (request) => {
|
|
537
598
|
setImageUrl("https://placehold.co/960x420/png");
|
|
538
599
|
setImageRequest(request);
|
|
539
|
-
}, onOpenPage: onOpenPage, onSelectionChange: setSelection, onContentChangeJSON: (json) => {
|
|
600
|
+
}, onOpenPage: onOpenPage, onOpenAttachment: (attachment) => void attachmentRuntime?.openAttachment?.(attachment), onSelectionChange: setSelection, onContentChangeJSON: (json) => {
|
|
540
601
|
syncDocument(contentFromNativeJson(json), false);
|
|
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 })] }));
|
|
602
|
+
}, 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(Modal, { animationType: "fade", onRequestClose: () => { attachmentAbortRef.current?.abort(); setAttachmentUpload(null); }, transparent: true, visible: attachmentUpload !== null, children: _jsx(View, { style: [styles.dialogBackdrop, { backgroundColor: resolvedTheme.backdrop }], children: _jsxs(View, { accessibilityViewIsModal: true, style: [styles.dialog, { backgroundColor: resolvedTheme.surface, borderColor: resolvedTheme.border }], children: [_jsx(Text, { style: [styles.unavailableTitle, { color: resolvedTheme.text }], children: attachmentUpload?.input.name }), _jsx(Text, { style: [styles.unavailableText, { color: attachmentUpload?.error ? "#b42318" : resolvedTheme.muted }], children: attachmentUpload?.error ?? `Uploading ${Math.round((attachmentUpload?.progress ?? 0) * 100)}%` }), _jsxs(View, { style: styles.dialogActions, children: [attachmentUpload?.error ? _jsx(CommandButton, { label: "Retry", onPress: () => void uploadAttachment(), theme: resolvedTheme }) : null, _jsx(CommandButton, { label: "Cancel", onPress: () => { attachmentAbortRef.current?.abort(); setAttachmentUpload(null); }, theme: resolvedTheme })] })] }) }) }), _jsx(UrlDialog, { title: "Image", value: imageUrl, visible: imageRequest !== null, placeholder: "https://", confirmLabel: "Insert", onChangeText: setImageUrl, onCancel: () => setImageRequest(null), onSubmit: submitImageDialog, theme: resolvedTheme })] }));
|
|
542
603
|
};
|
|
543
|
-
export const OpenEditorNativeViewer = ({ document = nativeSeedDocument, theme, renderers, onOpenPage, }) => {
|
|
604
|
+
export const OpenEditorNativeViewer = ({ document = nativeSeedDocument, theme, renderers, onOpenPage, attachmentRuntime, }) => {
|
|
544
605
|
const resolvedTheme = {
|
|
545
606
|
...defaultNativeTheme,
|
|
546
607
|
...theme,
|
|
@@ -550,7 +611,7 @@ export const OpenEditorNativeViewer = ({ document = nativeSeedDocument, theme, r
|
|
|
550
611
|
},
|
|
551
612
|
};
|
|
552
613
|
const normalizedDocument = normalizeForNativeEditor(document);
|
|
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)) }));
|
|
614
|
+
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, attachmentRuntime)) }));
|
|
554
615
|
};
|
|
555
616
|
const CommandButton = ({ label, active = false, primary = false, theme, onPress, }) => (_jsx(Pressable, { accessibilityRole: "button", accessibilityState: { selected: active }, onPress: onPress, style: [
|
|
556
617
|
styles.commandButton,
|
package/dist/toolbar.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare const openEditorNativeToolbarActionKeys: {
|
|
|
9
9
|
readonly toggleList: "toggleList";
|
|
10
10
|
readonly callout: "callout";
|
|
11
11
|
readonly page: "page";
|
|
12
|
+
readonly attachment: "attachment";
|
|
12
13
|
readonly moveBlockUp: "openeditor:block:moveUp";
|
|
13
14
|
readonly moveBlockDown: "openeditor:block:moveDown";
|
|
14
15
|
readonly undo: "openeditor:history:undo";
|
package/dist/toolbar.js
CHANGED
|
@@ -17,6 +17,7 @@ export const openEditorNativeToolbarActionKeys = {
|
|
|
17
17
|
toggleList: "toggleList",
|
|
18
18
|
callout: "callout",
|
|
19
19
|
page: "page",
|
|
20
|
+
attachment: "attachment",
|
|
20
21
|
moveBlockUp: "openeditor:block:moveUp",
|
|
21
22
|
moveBlockDown: "openeditor:block:moveDown",
|
|
22
23
|
undo: "openeditor:history:undo",
|
|
@@ -90,6 +91,12 @@ export const createOpenEditorNativeToolbarItems = ({ canUndo = true, canRedo = t
|
|
|
90
91
|
{ type: "image", label: "Image", icon: defaultIcon("image") },
|
|
91
92
|
],
|
|
92
93
|
},
|
|
94
|
+
{
|
|
95
|
+
type: "action",
|
|
96
|
+
key: openEditorNativeToolbarActionKeys.attachment,
|
|
97
|
+
label: "Upload file",
|
|
98
|
+
icon: platformIcon("paperclip", "attach-file", "File"),
|
|
99
|
+
},
|
|
93
100
|
{
|
|
94
101
|
type: "action",
|
|
95
102
|
key: openEditorNativeToolbarActionKeys.moveBlockUp,
|
|
@@ -171,6 +178,7 @@ export const nativeToolbarParityCoverage = () => {
|
|
|
171
178
|
["toggleList", openEditorNativeToolbarActionKeys.toggleList],
|
|
172
179
|
["callout", openEditorNativeToolbarActionKeys.callout],
|
|
173
180
|
["page", openEditorNativeToolbarActionKeys.page],
|
|
181
|
+
["attachment", openEditorNativeToolbarActionKeys.attachment],
|
|
174
182
|
]);
|
|
175
183
|
const markControls = new Map([
|
|
176
184
|
["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.14",
|
|
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.14",
|
|
31
|
+
"@openeditor/exporters": "0.0.14",
|
|
32
|
+
"@openeditor/extensions": "0.0.14",
|
|
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.14",
|
|
38
38
|
"react-native-keyboard-controller": ">=1.21",
|
|
39
39
|
"react": ">=19",
|
|
40
40
|
"react-native": ">=0.85"
|