Skip to content

Commit

Permalink
push advance example
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySerfaty committed Feb 4, 2024
1 parent f4c8b06 commit cb95f6f
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 146 deletions.
5 changes: 5 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"dependencies": {
"@react-navigation/native": "^6.1.9",
"@react-navigation/native-stack": "^6.9.17",
"@tiptap/extension-bubble-menu": "^2.2.1",
"@tiptap/extension-character-count": "^2.2.1",
"@tiptap/extension-document": "^2.2.1",
"@tiptap/extension-paragraph": "^2.2.1",
"@tiptap/extension-text": "^2.2.1",
"react": "18.2.0",
"react-native": "0.73.2",
"react-native-safe-area-context": "^4.8.2",
Expand Down
47 changes: 16 additions & 31 deletions example/src/Examples/Advanced/AdvancedRichText.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import React, { useRef } from 'react';
import {
SafeAreaView,
View,
KeyboardAvoidingView,
Platform,
StyleSheet,
} from 'react-native';
import { SafeAreaView, View, StyleSheet, Text } from 'react-native';
import {
ColorBridge,
HighlightBridge,
Expand All @@ -15,16 +9,14 @@ import {
RichText,
TaskListBridge,
TenTapStartKit,
Toolbar,
UnderlineBridge,
useNativeEditor,
useNativeEditorState,
} from 'tentap';

// @ts-ignore
import AdvancedEditor from './Editor/build/index.html';
import { CustomKeyboard } from '../../../../src/RichText/Keyboard';
import { ColorKeyboard } from '../../../../src/RichText/Keyboard/ColorKeyboard';
import { BubbleMenuBridge } from './BubbleMenuBridge';
import { CounterBridge } from './CounterBridge';

const exampleStyles = StyleSheet.create({
fullScreen: {
Expand All @@ -37,6 +29,17 @@ const exampleStyles = StyleSheet.create({
},
});

const Counter = ({ editor }) => {
const state = useNativeEditorState(editor);
return (
<View>
<Text>
{state.wordCount} || {state.characterCount}
</Text>
</View>
);
};

export const Advanced = ({}: NativeStackScreenProps<any, any, any>) => {
const editor = useNativeEditor({
initialContent: `<p>This is a basic example of implementing images.</p><img src="https://source.unsplash.com/8xznAGy4HcY/800x400" /><p>s sdfdsf fd dsfd ssdfd dsfdsfdsfdsfd</p>`,
Expand All @@ -48,15 +51,15 @@ export const Advanced = ({}: NativeStackScreenProps<any, any, any>) => {
LinkBridge,
ColorBridge,
HighlightBridge,
BubbleMenuBridge,
CounterBridge,
],
});
const TapRef = useRef(null);
const [activeKeyboard, setActiveKeyboard] = React.useState<string>();

return (
<SafeAreaView style={exampleStyles.fullScreen} ref={TapRef}>
<View style={exampleStyles.fullScreen}>
<Counter editor={editor} />
<RichText
avoidIosKeyboard
editor={editor}
Expand All @@ -65,24 +68,6 @@ export const Advanced = ({}: NativeStackScreenProps<any, any, any>) => {
customSource={AdvancedEditor}
/>
</View>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={exampleStyles.keyboardAvoidingView}
>
<Toolbar
activeKeyboard={activeKeyboard}
setActiveKeyboard={setActiveKeyboard}
editor={editor}
hidden={false}
/>
<CustomKeyboard
rootRef={TapRef}
activeKeyboardID={activeKeyboard}
setActiveKeyboardID={setActiveKeyboard}
keyboards={[ColorKeyboard]}
editor={editor}
/>
</KeyboardAvoidingView>
</SafeAreaView>
);
};
33 changes: 0 additions & 33 deletions example/src/Examples/Advanced/BubbleMenuBridge.ts

This file was deleted.

30 changes: 30 additions & 0 deletions example/src/Examples/Advanced/CounterBridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { TenTapBridge } from 'tentap';
import CharacterCount from '@tiptap/extension-character-count';

type CounterEditorState = {
wordCount: number;
characterCount: number;
};

type CounterEditorInstance = {};

declare module 'tentap' {
interface EditorNativeState extends CounterEditorState {}
interface EditorInstance extends CounterEditorInstance {}
}

export const CounterBridge = new TenTapBridge<
CounterEditorState,
CounterEditorInstance,
unknown
>({
tiptapExtension: CharacterCount.configure({
limit: 240,
}),
extendEditorState: (editor) => {
return {
wordCount: editor.storage.characterCount.characters(),
characterCount: editor.storage.characterCount.words(),
};
},
});
37 changes: 13 additions & 24 deletions example/src/Examples/Advanced/Editor/AdvancedEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
import React from 'react';
import { BubbleMenu, EditorContent } from '@tiptap/react';
import { sendMessage, useTenTap } from 'tentap';
import { EditorContent } from '@tiptap/react';
import { useTenTap } from 'tentap';
import Document from '@tiptap/extension-document';
import Paragraph from '@tiptap/extension-paragraph';
import Text from '@tiptap/extension-text';
import { CounterBridge } from '../CounterBridge';

export const AdvancedEditor = () => {
const editor = useTenTap();
// alert('ssss')
return (
<>
{editor && (
<BubbleMenu editor={editor || undefined}>
<button
onClick={() =>
window.ReactNativeWebView?.postMessage(
JSON.stringify({
type: 'new-comment',
})
)
}
>
Add comment
</button>
</BubbleMenu>
)}
<EditorContent editor={editor} />
</>
);
const editor = useTenTap({
bridges: [CounterBridge],
tiptapOptions: {
extensions: [Document, Paragraph, Text],
},
});
return <EditorContent editor={editor} />;
};
4 changes: 2 additions & 2 deletions example/src/Examples/Basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ const exampleStyles = StyleSheet.create({

export const Basic = ({}: NativeStackScreenProps<any, any, any>) => {
const editor = useNativeEditor({
initialContent: `<p>This is a basic example of implementing images.</p><img src="https://source.unsplash.com/8xznAGy4HcY/800x400" /><p>s</p>`,
initialContent: `<p>This is a basic <a href="https://google.com">example</a> of implementing images.</p><img src="https://source.unsplash.com/8xznAGy4HcY/800x400" /><p>s</p>`,
plugins: [
TenTapStartKit,
UnderlineBridge,
ImageBridge,
TaskListBridge,
LinkBridge,
LinkBridge.configure({ openOnClick: false }),
ColorBridge,
HighlightBridge,
],
Expand Down
10 changes: 10 additions & 0 deletions src/RichText/RichText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ export const RichText = ({
injectedJavaScriptBeforeContentLoaded={`${
editor.plugins
? `
window.plugConfig = '${JSON.stringify(
editor.plugins.reduce((acc, bridge) => {
return {
...acc,
[bridge.name]: bridge.config,
};
}, {})
)}';
window.whiteListPlugins = [${editor.plugins
.map((plugin) => `'${plugin.name}'`)
.join(',')}];
Expand Down
17 changes: 15 additions & 2 deletions src/bridges/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Editor, type AnyExtension } from '@tiptap/core';

interface TenTapBridge<T, E, M> {
name: string;
tiptapExtension?: AnyExtension | AnyExtension[];
tiptapExtension?: AnyExtension;
tiptapExtensionDeps?: AnyExtension[];
onBridgeMessage?: (
editor: Editor,
message: M,
Expand All @@ -12,17 +13,19 @@ interface TenTapBridge<T, E, M> {
extendEditorState?: (editor: Editor) => T;
extendEditorInstance?: (sendBridgeMessage: (message: M) => void) => E;
extendCSS?: string | undefined;
config?: string;
}

type CreateTenTapBridgeArgs<T, E, M> = Omit<
TenTapBridge<T, E, M> & { forceName?: string },
'name' | 'sendMessage'
'name' | 'sendMessage' | 'configure' | 'configureTiptapExtensionsOnRunTime'
>;

class TenTapBridge<T, E, M> {
constructor({
forceName,
tiptapExtension,
tiptapExtensionDeps,
onBridgeMessage,
onEditorMessage,
extendEditorState,
Expand All @@ -38,11 +41,21 @@ class TenTapBridge<T, E, M> {
}

this.tiptapExtension = tiptapExtension;
this.tiptapExtensionDeps = tiptapExtensionDeps;
this.onBridgeMessage = onBridgeMessage;
this.onEditorMessage = onEditorMessage;
this.extendEditorState = extendEditorState;
this.extendEditorInstance = extendEditorInstance;
this.extendCSS = extendCSS;
}

configure(config: any) {
this.config = config;
return this;
}
configureTiptapExtensionsOnRunTime(config: any) {
this.tiptapExtension = this.tiptapExtension?.configure(config);
return [this.tiptapExtension, ...(this.tiptapExtensionDeps || [])];
}
}
export default TenTapBridge;
3 changes: 2 additions & 1 deletion src/bridges/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const ColorBridge = new TenTapBridge<
ColorEditorInstance,
ColorMessage
>({
tiptapExtension: [TextStyle, Color],
tiptapExtension: Color,
tiptapExtensionDeps: [TextStyle],
onBridgeMessage: (editor, { type, payload }) => {
if (type === ColorEditorActionType.SetColor) {
editor
Expand Down
3 changes: 2 additions & 1 deletion src/bridges/highlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const HighlightBridge = new TenTapBridge<
HighlightEditorInstance,
HighlightMessage
>({
tiptapExtension: [TextStyle, Highlight.configure({ multicolor: true })],
tiptapExtension: Highlight.configure({ multicolor: true }),
tiptapExtensionDeps: [TextStyle],
onBridgeMessage: (editor, { type, payload }) => {
if (type === HighlightEditorActionType.SetHighlight) {
editor
Expand Down
3 changes: 2 additions & 1 deletion src/bridges/tasklist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export const TaskListBridge = new TenTapBridge<
TaskListEditorInstance,
TaskListMessage
>({
tiptapExtension: [TaskList, TaskItem],
tiptapExtension: TaskList,
tiptapExtensionDeps: [TaskItem],
onBridgeMessage: (editor, message) => {
if (message.type === TaskListEditorActionType.ToggleTaskList) {
editor.chain().focus().toggleTaskList().run();
Expand Down
25 changes: 23 additions & 2 deletions src/simpleWebEditor/Tiptap.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
import { EditorContent } from '@tiptap/react';
import { useTenTap } from './useTenTap';
import { useTenTap } from '../webEditorUtils';
import { TenTapStartKit } from '../bridges/StarterKit';
import { UnderlineBridge } from '../bridges/underline';
import { TaskListBridge } from '../bridges/tasklist';
import { LinkBridge } from '../bridges/link';
import { ColorBridge } from '../bridges/color';
import { HighlightBridge } from '../bridges/highlight';
import { CoreBridge } from '../bridges/core';
import { ImageBridge } from '../bridges/image';

let tenTapExtensions = [
TenTapStartKit,
UnderlineBridge,
ImageBridge,
TaskListBridge,
LinkBridge,
ColorBridge,
HighlightBridge,
CoreBridge,
].filter(
(e) => !window.whiteListPlugins || window.whiteListPlugins.includes(e.name)
);

export default function Tiptap() {
const editor = useTenTap();
const editor = useTenTap({ bridges: tenTapExtensions });

return <EditorContent editor={editor} />;

Check warning on line 28 in src/simpleWebEditor/Tiptap.tsx

View workflow job for this annotation

GitHub Actions / lint

'React' must be in scope when using JSX
}
3 changes: 2 additions & 1 deletion src/webEditorUtils/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './useTenTap';
export * from './useTenTap';
export { default as TenTapBridge } from '../bridges/base';
Loading

0 comments on commit cb95f6f

Please sign in to comment.