@openeditor/native 0.0.33 → 0.0.35
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 +81 -58
- package/dist/controller.d.ts +79 -0
- package/dist/controller.js +254 -0
- package/dist/index.d.ts +6 -101
- package/dist/index.js +4 -910
- package/dist/native-editor.d.ts +48 -0
- package/dist/native-editor.js +214 -0
- package/dist/native-layout.d.ts +20 -0
- package/dist/native-layout.js +15 -0
- package/dist/native-provider.d.ts +9 -0
- package/dist/native-provider.js +9 -0
- package/dist/theme.d.ts +32 -2
- package/dist/theme.js +56 -37
- package/dist/toolbar-host.d.ts +20 -0
- package/dist/toolbar-host.js +211 -0
- package/dist/toolbar-items.d.ts +109 -0
- package/dist/toolbar-items.js +57 -0
- package/dist/toolbar-surface.d.ts +17 -0
- package/dist/toolbar-surface.js +33 -0
- package/package.json +18 -19
- package/plugin.cjs +79 -0
- package/dist/document.d.ts +0 -7
- package/dist/document.js +0 -69
- package/dist/emoji-button.d.ts +0 -8
- package/dist/emoji-button.js +0 -14
- package/dist/emoji-data.d.ts +0 -44
- package/dist/emoji-data.js +0 -50
- package/dist/emoji-picker.d.ts +0 -12
- package/dist/emoji-picker.js +0 -67
- package/dist/selection.d.ts +0 -3
- package/dist/selection.js +0 -32
- package/dist/toolbar.d.ts +0 -30
- package/dist/toolbar.js +0 -282
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { OpenEditorDocument, OpenEditorPageSnapshot } from "@openeditor/core";
|
|
2
|
+
import type { GlassColorScheme } from "expo-glass-effect";
|
|
3
|
+
import { type OpenEditorRuntimeState, type OpenEditorNativeEffectName, type OpenEditorTheme } from "@openeditor/embedded-runtime";
|
|
4
|
+
import { type ReactNode, type RefAttributes } from "react";
|
|
5
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
6
|
+
import { type WebViewProps } from "react-native-webview";
|
|
7
|
+
import { type OpenEditorNativeController, type OpenEditorNativeEffectHandlers } from "./controller.js";
|
|
8
|
+
import { type OpenEditorNativeToolbarItem } from "./toolbar-host.js";
|
|
9
|
+
import { type OpenEditorNativeContentInsets } from "./native-layout.js";
|
|
10
|
+
export type { OpenEditorNativeContentInsets } from "./native-layout.js";
|
|
11
|
+
export type OpenEditorNativeTheme = Partial<OpenEditorTheme>;
|
|
12
|
+
type EdgeInsets = OpenEditorNativeContentInsets;
|
|
13
|
+
type OwnedWebViewProps = "source" | "onMessage" | "style" | "scrollEnabled" | "nestedScrollEnabled";
|
|
14
|
+
export type OpenEditorNativeProps = {
|
|
15
|
+
initialDocument: OpenEditorDocument;
|
|
16
|
+
/** Page metadata rendered inside the shared, scroll-owned document surface. */
|
|
17
|
+
page?: OpenEditorPageSnapshot;
|
|
18
|
+
editable?: boolean;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
theme?: OpenEditorNativeTheme;
|
|
21
|
+
contentInsets?: Partial<EdgeInsets>;
|
|
22
|
+
showToolbar?: boolean;
|
|
23
|
+
toolbarItems?: readonly OpenEditorNativeToolbarItem[];
|
|
24
|
+
renderToolbar?: (context: {
|
|
25
|
+
availableNativeEffects: readonly OpenEditorNativeEffectName[];
|
|
26
|
+
blockHandlesVisible: boolean;
|
|
27
|
+
controller: OpenEditorNativeController;
|
|
28
|
+
setBlockHandlesVisible: (visible: boolean) => void;
|
|
29
|
+
state: OpenEditorRuntimeState;
|
|
30
|
+
}) => ReactNode;
|
|
31
|
+
nativeEffects?: OpenEditorNativeEffectHandlers;
|
|
32
|
+
onDocumentChanged?: (change: {
|
|
33
|
+
documentRevision: number;
|
|
34
|
+
origin: "input" | "command";
|
|
35
|
+
}) => void;
|
|
36
|
+
onReady?: (controller: OpenEditorNativeController) => void;
|
|
37
|
+
onError?: (error: Error) => void;
|
|
38
|
+
toolbarContentInset?: number;
|
|
39
|
+
toolbarOffset?: {
|
|
40
|
+
closed?: number;
|
|
41
|
+
opened?: number;
|
|
42
|
+
};
|
|
43
|
+
toolbarColorScheme?: GlassColorScheme;
|
|
44
|
+
toolbarContainerStyle?: StyleProp<ViewStyle>;
|
|
45
|
+
style?: StyleProp<ViewStyle>;
|
|
46
|
+
webViewProps?: Omit<WebViewProps, OwnedWebViewProps>;
|
|
47
|
+
};
|
|
48
|
+
export declare const OpenEditorNative: import("react").ForwardRefExoticComponent<OpenEditorNativeProps & RefAttributes<OpenEditorNativeController>>;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { openEditorEmbeddedSurfaceHtml } from "@openeditor/embedded-surface/html";
|
|
3
|
+
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, } from "react";
|
|
4
|
+
import { Keyboard, Platform, StyleSheet, useColorScheme, View, } from "react-native";
|
|
5
|
+
import { KeyboardStickyView } from "react-native-keyboard-controller";
|
|
6
|
+
import { WebView, } from "react-native-webview";
|
|
7
|
+
import { emptyOpenEditorNativeState, isOpenEditorNativeLifecycleCancellation, OpenEditorNativeBridge, } from "./controller.js";
|
|
8
|
+
import { OpenEditorNativeToolbar, } from "./toolbar-host.js";
|
|
9
|
+
import { OpenEditorNativeToolbarSurface } from "./toolbar-surface.js";
|
|
10
|
+
import { OPENEDITOR_NATIVE_TOOLBAR_OFFSET, OPENEDITOR_NATIVE_TOOLBAR_CONTENT_INSET, OPENEDITOR_NATIVE_TOOLBAR_HEIGHT, OPENEDITOR_NATIVE_TOOLBAR_RADIUS, resolveOpenEditorNativeContentInsets, } from "./native-layout.js";
|
|
11
|
+
import { resolveOpenEditorNativeTheme } from "./theme.js";
|
|
12
|
+
const DEFAULT_INSETS = { top: 0, right: 16, bottom: 0, left: 16 };
|
|
13
|
+
const HostWebView = WebView;
|
|
14
|
+
export const OpenEditorNative = forwardRef(function OpenEditorNative({ initialDocument, page, editable = true, placeholder = "Start writing…", theme, contentInsets = DEFAULT_INSETS, showToolbar = true, toolbarItems, renderToolbar, nativeEffects, onDocumentChanged, onReady, onError, toolbarContentInset = OPENEDITOR_NATIVE_TOOLBAR_CONTENT_INSET, toolbarOffset = OPENEDITOR_NATIVE_TOOLBAR_OFFSET, toolbarColorScheme, toolbarContainerStyle, style, webViewProps, }, forwardedRef) {
|
|
15
|
+
const systemColorScheme = useColorScheme();
|
|
16
|
+
const resolvedColorScheme = systemColorScheme === "dark" ? "dark" : "light";
|
|
17
|
+
const resolvedTheme = useMemo(() => resolveOpenEditorNativeTheme(theme, resolvedColorScheme), [resolvedColorScheme, theme]);
|
|
18
|
+
const resolvedToolbarColorScheme = toolbarColorScheme ?? resolvedColorScheme;
|
|
19
|
+
const webViewRef = useRef(null);
|
|
20
|
+
const sessionIdRef = useRef(`native_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`);
|
|
21
|
+
const callbacksRef = useRef({
|
|
22
|
+
nativeEffects,
|
|
23
|
+
onDocumentChanged,
|
|
24
|
+
onError,
|
|
25
|
+
onReady,
|
|
26
|
+
});
|
|
27
|
+
callbacksRef.current = { nativeEffects, onDocumentChanged, onError, onReady };
|
|
28
|
+
const initialDocumentRef = useRef(initialDocument);
|
|
29
|
+
const initialConfigRef = useRef({ editable, placeholder, theme: resolvedTheme });
|
|
30
|
+
const initializedRef = useRef(false);
|
|
31
|
+
const bridgeLifetimeRef = useRef(0);
|
|
32
|
+
const [editorState, setEditorState] = useState(emptyOpenEditorNativeState);
|
|
33
|
+
const [blockHandlesVisible, setBlockHandlesVisible] = useState(false);
|
|
34
|
+
const [keyboardVisible, setKeyboardVisible] = useState(() => Keyboard.isVisible?.() ?? false);
|
|
35
|
+
const [bridge] = useState(() => new OpenEditorNativeBridge({
|
|
36
|
+
sessionId: sessionIdRef.current,
|
|
37
|
+
send: (message) => webViewRef.current?.postMessage(message),
|
|
38
|
+
getEffectHandlers: () => callbacksRef.current.nativeEffects,
|
|
39
|
+
}));
|
|
40
|
+
// The packaged HTML is several megabytes. Keeping the source object stable is
|
|
41
|
+
// essential: passing a fresh inline source through React Native on each editor
|
|
42
|
+
// state update can make WKWebView reload it and can terminate its content
|
|
43
|
+
// process under memory pressure.
|
|
44
|
+
const runtimeSource = useMemo(() => ({
|
|
45
|
+
html: openEditorEmbeddedSurfaceHtml,
|
|
46
|
+
baseUrl: "https://openeditor.local/",
|
|
47
|
+
}), []);
|
|
48
|
+
useImperativeHandle(forwardedRef, () => bridge, [bridge]);
|
|
49
|
+
const resolvedInsets = resolveOpenEditorNativeContentInsets({
|
|
50
|
+
contentInsets,
|
|
51
|
+
editable,
|
|
52
|
+
showToolbar,
|
|
53
|
+
toolbarContentInset,
|
|
54
|
+
});
|
|
55
|
+
const availableNativeEffects = Object.keys(nativeEffects ?? {});
|
|
56
|
+
const hostConfig = JSON.stringify({
|
|
57
|
+
availableNativeEffects,
|
|
58
|
+
blockHandles: editable && blockHandlesVisible,
|
|
59
|
+
contentInsets: resolvedInsets,
|
|
60
|
+
page,
|
|
61
|
+
placeholder,
|
|
62
|
+
sessionId: sessionIdRef.current,
|
|
63
|
+
theme: resolvedTheme,
|
|
64
|
+
});
|
|
65
|
+
const injectedConfig = `window.__OPENEDITOR_NATIVE_HOST__=${hostConfig};true;`;
|
|
66
|
+
const hostConfigUpdateScript = `window.dispatchEvent(new CustomEvent("openeditor:host-config",{detail:${JSON.stringify({
|
|
67
|
+
blockHandles: editable && blockHandlesVisible,
|
|
68
|
+
contentInsets: resolvedInsets,
|
|
69
|
+
page,
|
|
70
|
+
placeholder,
|
|
71
|
+
theme: resolvedTheme,
|
|
72
|
+
})}}));true;`;
|
|
73
|
+
const initializeRuntime = useCallback(() => {
|
|
74
|
+
if (!bridge.runtimeReady || initializedRef.current)
|
|
75
|
+
return;
|
|
76
|
+
initializedRef.current = true;
|
|
77
|
+
void bridge
|
|
78
|
+
.initialize(initialDocumentRef.current, initialConfigRef.current.editable)
|
|
79
|
+
.then((result) => {
|
|
80
|
+
bridge.markInitialized();
|
|
81
|
+
setEditorState((state) => ({
|
|
82
|
+
...state,
|
|
83
|
+
documentRevision: result.documentRevision,
|
|
84
|
+
revision: result.stateRevision,
|
|
85
|
+
editable: initialConfigRef.current.editable,
|
|
86
|
+
}));
|
|
87
|
+
callbacksRef.current.onReady?.(bridge);
|
|
88
|
+
})
|
|
89
|
+
.catch((error) => {
|
|
90
|
+
initializedRef.current = false;
|
|
91
|
+
if (isOpenEditorNativeLifecycleCancellation(error))
|
|
92
|
+
return;
|
|
93
|
+
callbacksRef.current.onError?.(error instanceof Error
|
|
94
|
+
? error
|
|
95
|
+
: new Error("OpenEditor runtime initialization failed."));
|
|
96
|
+
});
|
|
97
|
+
}, [bridge]);
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
webViewRef.current?.injectJavaScript(hostConfigUpdateScript);
|
|
100
|
+
}, [hostConfigUpdateScript]);
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
const showSubscription = Keyboard.addListener(Platform.OS === "ios" ? "keyboardWillShow" : "keyboardDidShow", () => setKeyboardVisible(true));
|
|
103
|
+
const hideSubscription = Keyboard.addListener(Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide", () => setKeyboardVisible(false));
|
|
104
|
+
return () => {
|
|
105
|
+
showSubscription.remove();
|
|
106
|
+
hideSubscription.remove();
|
|
107
|
+
};
|
|
108
|
+
}, []);
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
const unsubscribe = bridge.subscribe((event) => {
|
|
111
|
+
if (event.type === "ready") {
|
|
112
|
+
initializeRuntime();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (event.type === "stateChanged") {
|
|
116
|
+
setEditorState(event.state);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (event.type === "documentChanged") {
|
|
120
|
+
if (bridge.ready) {
|
|
121
|
+
callbacksRef.current.onDocumentChanged?.({
|
|
122
|
+
documentRevision: event.documentRevision,
|
|
123
|
+
origin: event.origin,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (event.type === "error") {
|
|
129
|
+
callbacksRef.current.onError?.(new Error(`${event.code}: ${event.message}`));
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return unsubscribe;
|
|
133
|
+
}, [bridge, initializeRuntime]);
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
const lifetime = ++bridgeLifetimeRef.current;
|
|
136
|
+
return () => {
|
|
137
|
+
queueMicrotask(() => {
|
|
138
|
+
if (bridgeLifetimeRef.current === lifetime)
|
|
139
|
+
bridge.dispose();
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
}, [bridge]);
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
let active = true;
|
|
145
|
+
void bridge
|
|
146
|
+
.command({ type: "setEditable", editable })
|
|
147
|
+
.catch((error) => {
|
|
148
|
+
if (active && !isOpenEditorNativeLifecycleCancellation(error)) {
|
|
149
|
+
callbacksRef.current.onError?.(error instanceof Error
|
|
150
|
+
? error
|
|
151
|
+
: new Error("OpenEditor could not update editability."));
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return () => {
|
|
155
|
+
active = false;
|
|
156
|
+
};
|
|
157
|
+
}, [bridge, editable]);
|
|
158
|
+
const onMessage = (event) => {
|
|
159
|
+
if (!bridge.receive(event.nativeEvent.data)) {
|
|
160
|
+
callbacksRef.current.onError?.(new Error("OpenEditor runtime sent an invalid bridge message."));
|
|
161
|
+
}
|
|
162
|
+
initializeRuntime();
|
|
163
|
+
};
|
|
164
|
+
const toolbarEnabled = showToolbar && editable;
|
|
165
|
+
const shouldRenderToolbar = showToolbar && editable && editorState.focused && keyboardVisible;
|
|
166
|
+
const toolbar = renderToolbar && shouldRenderToolbar ? (renderToolbar({
|
|
167
|
+
availableNativeEffects,
|
|
168
|
+
blockHandlesVisible,
|
|
169
|
+
controller: bridge,
|
|
170
|
+
setBlockHandlesVisible,
|
|
171
|
+
state: editorState,
|
|
172
|
+
})) : !renderToolbar && toolbarEnabled ? (_jsx(OpenEditorNativeToolbar, { availableNativeEffects: availableNativeEffects, blockHandlesVisible: blockHandlesVisible, controller: bridge, items: toolbarItems, onBlockHandlesVisibleChange: setBlockHandlesVisible, onCommandError: (error) => callbacksRef.current.onError?.(error), state: editorState, style: styles.toolbarContent, theme: resolvedTheme, visible: shouldRenderToolbar })) : null;
|
|
173
|
+
return (_jsxs(View, { style: [
|
|
174
|
+
styles.host,
|
|
175
|
+
{ backgroundColor: resolvedTheme.surface },
|
|
176
|
+
style,
|
|
177
|
+
], children: [_jsx(View, { style: styles.webViewContainer, children: _jsx(HostWebView, { ...webViewProps, allowsBackForwardNavigationGestures: false, bounces: webViewProps?.bounces ?? true, injectedJavaScriptBeforeContentLoaded: injectedConfig, javaScriptEnabled: true, hideKeyboardAccessoryView: webViewProps?.hideKeyboardAccessoryView ?? true, nestedScrollEnabled: true, onLoadStart: (event) => {
|
|
178
|
+
initializedRef.current = false;
|
|
179
|
+
bridge.resetRuntime();
|
|
180
|
+
webViewProps?.onLoadStart?.(event);
|
|
181
|
+
}, onContentProcessDidTerminate: (event) => {
|
|
182
|
+
callbacksRef.current.onError?.(new Error("OpenEditor WebView content process terminated unexpectedly."));
|
|
183
|
+
webViewProps?.onContentProcessDidTerminate?.(event);
|
|
184
|
+
}, onMessage: onMessage, originWhitelist: webViewProps?.originWhitelist ?? [
|
|
185
|
+
"https://openeditor.local",
|
|
186
|
+
"file://*",
|
|
187
|
+
"about:blank",
|
|
188
|
+
], ref: webViewRef, scrollEnabled: true, source: runtimeSource, style: [
|
|
189
|
+
styles.webView,
|
|
190
|
+
{
|
|
191
|
+
backgroundColor: resolvedTheme.surface,
|
|
192
|
+
},
|
|
193
|
+
] }) }), toolbarEnabled ? (_jsx(KeyboardStickyView, { offset: toolbarOffset, pointerEvents: "box-none", style: [styles.toolbarContainer, toolbarContainerStyle], children: _jsx(OpenEditorNativeToolbarSurface, { active: shouldRenderToolbar, colorScheme: resolvedToolbarColorScheme, theme: resolvedTheme, children: toolbar }) })) : null] }));
|
|
194
|
+
});
|
|
195
|
+
const styles = StyleSheet.create({
|
|
196
|
+
host: { flex: 1, minHeight: 0 },
|
|
197
|
+
webViewContainer: { flex: 1, minHeight: 0, overflow: "hidden" },
|
|
198
|
+
webView: { flex: 1 },
|
|
199
|
+
toolbarContainer: {
|
|
200
|
+
bottom: 0,
|
|
201
|
+
borderRadius: OPENEDITOR_NATIVE_TOOLBAR_RADIUS,
|
|
202
|
+
height: OPENEDITOR_NATIVE_TOOLBAR_HEIGHT,
|
|
203
|
+
left: 12,
|
|
204
|
+
overflow: "hidden",
|
|
205
|
+
position: "absolute",
|
|
206
|
+
right: 12,
|
|
207
|
+
zIndex: 20,
|
|
208
|
+
},
|
|
209
|
+
toolbarContent: {
|
|
210
|
+
backgroundColor: "transparent",
|
|
211
|
+
borderWidth: 0,
|
|
212
|
+
minHeight: OPENEDITOR_NATIVE_TOOLBAR_HEIGHT,
|
|
213
|
+
},
|
|
214
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type OpenEditorNativeContentInsets = {
|
|
2
|
+
top: number;
|
|
3
|
+
right: number;
|
|
4
|
+
bottom: number;
|
|
5
|
+
left: number;
|
|
6
|
+
};
|
|
7
|
+
export declare const OPENEDITOR_NATIVE_TOOLBAR_HEIGHT = 46;
|
|
8
|
+
export declare const OPENEDITOR_NATIVE_TOOLBAR_RADIUS: number;
|
|
9
|
+
export declare const OPENEDITOR_NATIVE_TOOLBAR_CONTENT_INSET = 70;
|
|
10
|
+
export declare const OPENEDITOR_NATIVE_TOOLBAR_OFFSET: {
|
|
11
|
+
readonly closed: 0;
|
|
12
|
+
/** Keep the intentional breathing room above the software keyboard. */
|
|
13
|
+
readonly opened: -8;
|
|
14
|
+
};
|
|
15
|
+
export declare const resolveOpenEditorNativeContentInsets: ({ contentInsets, editable, showToolbar, toolbarContentInset, }: {
|
|
16
|
+
contentInsets: Partial<OpenEditorNativeContentInsets>;
|
|
17
|
+
editable: boolean;
|
|
18
|
+
showToolbar: boolean;
|
|
19
|
+
toolbarContentInset: number;
|
|
20
|
+
}) => OpenEditorNativeContentInsets;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const OPENEDITOR_NATIVE_TOOLBAR_HEIGHT = 46;
|
|
2
|
+
export const OPENEDITOR_NATIVE_TOOLBAR_RADIUS = OPENEDITOR_NATIVE_TOOLBAR_HEIGHT / 2;
|
|
3
|
+
export const OPENEDITOR_NATIVE_TOOLBAR_CONTENT_INSET = 70;
|
|
4
|
+
export const OPENEDITOR_NATIVE_TOOLBAR_OFFSET = {
|
|
5
|
+
closed: 0,
|
|
6
|
+
/** Keep the intentional breathing room above the software keyboard. */
|
|
7
|
+
opened: -8,
|
|
8
|
+
};
|
|
9
|
+
export const resolveOpenEditorNativeContentInsets = ({ contentInsets, editable, showToolbar, toolbarContentInset, }) => ({
|
|
10
|
+
top: contentInsets.top ?? 0,
|
|
11
|
+
right: contentInsets.right ?? 0,
|
|
12
|
+
bottom: (contentInsets.bottom ?? 0) +
|
|
13
|
+
(showToolbar && editable ? toolbarContentInset : 0),
|
|
14
|
+
left: contentInsets.left ?? 0,
|
|
15
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from "react";
|
|
2
|
+
export type OpenEditorNativeProviderProps = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Owns the native keyboard animation context used by OpenEditor's toolbar.
|
|
7
|
+
* Mount once above every OpenEditorNative instance, normally at the app root.
|
|
8
|
+
*/
|
|
9
|
+
export declare function OpenEditorNativeProvider({ children }: OpenEditorNativeProviderProps): ReactElement;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { KeyboardProvider } from "react-native-keyboard-controller";
|
|
3
|
+
/**
|
|
4
|
+
* Owns the native keyboard animation context used by OpenEditor's toolbar.
|
|
5
|
+
* Mount once above every OpenEditorNative instance, normally at the app root.
|
|
6
|
+
*/
|
|
7
|
+
export function OpenEditorNativeProvider({ children }) {
|
|
8
|
+
return _jsx(KeyboardProvider, { children: children });
|
|
9
|
+
}
|
package/dist/theme.d.ts
CHANGED
|
@@ -1,2 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import type { OpenEditorTheme } from "@openeditor/embedded-runtime";
|
|
2
|
+
export type OpenEditorNativeColorScheme = "light" | "dark";
|
|
3
|
+
declare const LIGHT_THEME: {
|
|
4
|
+
surface: string;
|
|
5
|
+
surfaceRaised: string;
|
|
6
|
+
surfaceMuted: string;
|
|
7
|
+
interactionHover: string;
|
|
8
|
+
interactionSelected: string;
|
|
9
|
+
blockSurface: string;
|
|
10
|
+
text: string;
|
|
11
|
+
textSoft: string;
|
|
12
|
+
heading: string;
|
|
13
|
+
muted: string;
|
|
14
|
+
placeholder: string;
|
|
15
|
+
border: string;
|
|
16
|
+
borderStrong: string;
|
|
17
|
+
structuralLine: string;
|
|
18
|
+
accent: string;
|
|
19
|
+
accentText: string;
|
|
20
|
+
accentStrong: string;
|
|
21
|
+
buttonBackground: string;
|
|
22
|
+
buttonText: string;
|
|
23
|
+
codeBackground: string;
|
|
24
|
+
codeText: string;
|
|
25
|
+
link: string;
|
|
26
|
+
linkHover: string;
|
|
27
|
+
shadow: string;
|
|
28
|
+
fontSans: string;
|
|
29
|
+
};
|
|
30
|
+
export type ResolvedOpenEditorNativeTheme = typeof LIGHT_THEME;
|
|
31
|
+
export declare const resolveOpenEditorNativeTheme: (theme: Partial<OpenEditorTheme> | undefined, colorScheme: OpenEditorNativeColorScheme) => ResolvedOpenEditorNativeTheme;
|
|
32
|
+
export {};
|
package/dist/theme.js
CHANGED
|
@@ -1,39 +1,58 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
const LIGHT_THEME = {
|
|
2
|
+
surface: "#ffffff",
|
|
3
|
+
surfaceRaised: "#ffffff",
|
|
4
|
+
surfaceMuted: "#f5f5f5",
|
|
5
|
+
interactionHover: "#f5f5f5",
|
|
6
|
+
interactionSelected: "#e5e5e5",
|
|
7
|
+
blockSurface: "#fafafa",
|
|
8
|
+
text: "#171717",
|
|
9
|
+
textSoft: "#404040",
|
|
10
|
+
heading: "#0a0a0a",
|
|
11
|
+
muted: "#737373",
|
|
12
|
+
placeholder: "#a3a3a3",
|
|
13
|
+
border: "#e5e5e5",
|
|
14
|
+
borderStrong: "#d4d4d4",
|
|
15
|
+
structuralLine: "#e5e5e5",
|
|
16
|
+
accent: "#171717",
|
|
17
|
+
accentText: "#ffffff",
|
|
18
|
+
accentStrong: "#0a0a0a",
|
|
19
|
+
buttonBackground: "#ffffff",
|
|
20
|
+
buttonText: "#171717",
|
|
21
|
+
codeBackground: "#f5f5f5",
|
|
22
|
+
codeText: "#262626",
|
|
23
|
+
link: "#1d4ed8",
|
|
24
|
+
linkHover: "#1e40af",
|
|
25
|
+
shadow: "rgba(0,0,0,0.18)",
|
|
26
|
+
fontSans: '-apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", sans-serif',
|
|
16
27
|
};
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
const DARK_THEME = {
|
|
29
|
+
surface: "#111111",
|
|
30
|
+
surfaceRaised: "#1c1c1e",
|
|
31
|
+
surfaceMuted: "#27272a",
|
|
32
|
+
interactionHover: "#333336",
|
|
33
|
+
interactionSelected: "#3a3a3c",
|
|
34
|
+
blockSurface: "#1c1c1e",
|
|
35
|
+
text: "#f5f5f5",
|
|
36
|
+
textSoft: "#d4d4d4",
|
|
37
|
+
heading: "#fafafa",
|
|
38
|
+
muted: "#a3a3a3",
|
|
39
|
+
placeholder: "#737373",
|
|
40
|
+
border: "#333333",
|
|
41
|
+
borderStrong: "#525252",
|
|
42
|
+
structuralLine: "#333333",
|
|
43
|
+
accent: "#f5f5f5",
|
|
44
|
+
accentText: "#111111",
|
|
45
|
+
accentStrong: "#ffffff",
|
|
46
|
+
buttonBackground: "#27272a",
|
|
47
|
+
buttonText: "#f5f5f5",
|
|
48
|
+
codeBackground: "#1f1f1f",
|
|
49
|
+
codeText: "#e5e5e5",
|
|
50
|
+
link: "#60a5fa",
|
|
51
|
+
linkHover: "#93c5fd",
|
|
52
|
+
shadow: "rgba(0,0,0,0.60)",
|
|
53
|
+
fontSans: '-apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", sans-serif',
|
|
39
54
|
};
|
|
55
|
+
export const resolveOpenEditorNativeTheme = (theme, colorScheme) => ({
|
|
56
|
+
...(colorScheme === "dark" ? DARK_THEME : LIGHT_THEME),
|
|
57
|
+
...theme,
|
|
58
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OpenEditorNativeEffectName, OpenEditorRuntimeState } from "@openeditor/embedded-runtime";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import type { OpenEditorNativeController } from "./controller.js";
|
|
4
|
+
import type { OpenEditorNativeTheme } from "./native-editor.js";
|
|
5
|
+
import { type OpenEditorNativeToolbarItem } from "./toolbar-items.js";
|
|
6
|
+
export type { OpenEditorNativeToolbarItem } from "./toolbar-items.js";
|
|
7
|
+
export { defaultOpenEditorNativeToolbarItems, openEditorNativeBlockPickerItems, } from "./toolbar-items.js";
|
|
8
|
+
export type OpenEditorNativeToolbarProps = {
|
|
9
|
+
availableNativeEffects?: readonly OpenEditorNativeEffectName[];
|
|
10
|
+
controller: OpenEditorNativeController;
|
|
11
|
+
state: OpenEditorRuntimeState;
|
|
12
|
+
items?: readonly OpenEditorNativeToolbarItem[];
|
|
13
|
+
theme?: OpenEditorNativeTheme;
|
|
14
|
+
style?: StyleProp<ViewStyle>;
|
|
15
|
+
onCommandError?: (error: Error) => void;
|
|
16
|
+
visible?: boolean;
|
|
17
|
+
blockHandlesVisible?: boolean;
|
|
18
|
+
onBlockHandlesVisibleChange?: (visible: boolean) => void;
|
|
19
|
+
};
|
|
20
|
+
export declare const OpenEditorNativeToolbar: import("react").MemoExoticComponent<({ availableNativeEffects, controller, state, items, theme, style, onCommandError, visible, blockHandlesVisible, onBlockHandlesVisibleChange, }: OpenEditorNativeToolbarProps) => import("react").JSX.Element>;
|